neuling braucht hilfe

Fragen zu Tkinter.
Antworten
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

hallo
versuche mit tkinter eine zeiterfassung am pi zu machen, leider klappt das nicht so wie ich es mir vorstelle, das frame oder die labels oder die buttons sollten alle 2 sekunden updaten, zb. erst wird in der DB geschaut wer da ist dann werden die entsprechenden labels mit users gefüllt die buttons werden mit entsprechenden befehlen kommen, pause etc gefüllt, dann geht ein user in die pause drückt den button pause, jetzt sollte das ganze Frame oder ?????? updaten und bei dem user anzeigen das er in der pause ist und im nur noch ein button zu verfügung stehen "kommen", ich bekomme den update nicht hin wenn ich das fenster schließe kommt ein neues fenster und alles ist richtig (loop), jedoch möchte ich nicht das man das fenster schliest um den update hin zu bekommen.
Das mein erster versuch mit tkinter, bin neuling.
Ich werde mal den code dran hängen (ist jetzt nur der erste versuch es soll funktionieren, danach möchte ich versuchen den code zu vereinfachen), vielleicht kann mir einer helfen.
Danke im Voraus

code:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-


#test 08.10.2014
# Zeitkorrektur = !
# Abwesend = g
# Pause = p
# Mittag=m
# Arbeit = k

import MySQLdb
import sys
import ftplib
import time
import datetime
import os
import subprocess
from subprocess import Popen, PIPE, STDOUT
from Tkinter import *
#import Tkinter as tk



while True:
	#data = True
	ts = time.time()
	sec = int(ts)
	dat = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d')
	zeit = datetime.datetime.fromtimestamp(ts).strftime('%H:%M:%S')
	zeit1 = datetime.datetime.fromtimestamp(ts).strftime('%H')
	time1 = ''
	aus = 0 #wird später benötigt 
	an = 0 #wird später benötigt 
	b = 0 #ein test wird eigentlich nicht benötigt
	
	"""verbindung zu DB ****,******"""
	db=MySQLdb.connect("*****","****","****l","****")
	#verbindung zu richtigen db
	#db=MySQLdb.connect ("*****","*****","****","*****")
	#"""steht verbindung, wenn ja dann weiter"""
	#"""if (db):
	#       print "alles ok!"
	#       else:
	#               print "etwas stimmt nicht!" """
	#       """etwas aus db auslesen"""
	cursor = db.cursor()
	rfidnr = open("/***/****/****/test.txt").read() #test für einen user wird ersetzt
	query = "SELECT idx, status FROM users WHERE RFID = '" + (rfidnr) + "'"
	cursor.execute(query)
	row = cursor.fetchall()
	for row0 in cursor:
		idx_user = row0[0]
		stat = row0[1]

	class Gui(object):

		def an(self):
			self.butan.config(text='An')

		def aus(self):
			self.butaus.config(text='Aus')
		
		### definition buttons ### 
#hier definiere ich die buttons sieht nicht gut, mit meinem kentniss stand habe ich es im moment nicht besser hinbekommen
		def buttonk(self):
			db=MySQLdb.connect("****","****","***","****")
			cursor = db.cursor()
			stat = "SELECT idx, status FROM users WHERE RFID = '" + (rfidnr) + "'"
			cursor.execute(stat)
			row = cursor.fetchall()
			for row0 in cursor:
				idx_user = row0[0]
				stat = row0[1]
					
			if (stat == 'g' or stat == ''):
				cursor.execute("UPDATE users SET status='k' WHERE idx = %s",(idx_user))
				cursor.execute("INSERT INTO Zeitstempel (idx, Datum, Uhrzeit, Sekunden, Status) VALUES (%s, %s, %s, %s, %s)",(idx_user,dat,zeit,sec,'k'))
			elif (stat == 'p' or stat == 'm' or stat == 'd'):
				cursor.execute("UPDATE users SET status='k' WHERE idx = %s",(idx_user))
				cursor.execute("SELECT status, Uhrzeit FROM Zeitstempel WHERE idx = %s AND Datum = %s AND Status = %s Order by Sekunden DESC",(idx_user,dat,stat))
				row5 = cursor.fetchall()
				for row5 in cursor:
					z1 = row5[1]
					statn = row5[0]
					if z1 != 0:
						cursor.execute("INSERT INTO Arbeitszeit (idx, Datum, z1, z2, status) VALUES (%s, %s, %s, %s, %s)",(idx_user,dat,z1,zeit,statn))
						cursor.execute("DELETE FROM Zeitstempel WHERE idx = %s AND status = %s AND Datum = %s",(idx_user,statn,dat))
			cursor.close()
			db.close()

		def buttonp(self):
			db=MySQLdb.connect("*****","****","****","*****")
			cursor = db.cursor()
			cursor.execute("""UPDATE users SET status = 'p' WHERE idx = %s""",(idx_user))
			cursor.execute("""INSERT INTO Zeitstempel (idx, Datum, Uhrzeit, Sekunden, Status) VALUES (%s, %s, %s, %s, %s)""",(idx_user,dat,zeit,sec,'p'))
			cursor.close()
			db.close()

		def buttonm(self):
			db=MySQLdb.connect("*****","****","****","*****")
			cursor = db.cursor()
			cursor.execute("UPDATE users SET status = 'm' WHERE idx = %s",(idx_user))
			cursor.execute("INSERT INTO Zeitstempel (idx, Datum, Uhrzeit, Sekunden, Status) VALUES (%s, %s, %s, %s, %s)",(idx_user,dat,zeit,sec,'m'))
			cursor.close()
			db.close()

		def buttond(self):
			db=MySQLdb.connect("*****","****","****","*****")
			cursor = db.cursor()
			cursor.execute("UPDATE users SET status = 'd' WHERE idx = %s", (idx_user))
			cursor.execute("INSERT INTO Zeitstempel (idx, Datum, Uhrzeit, Sekunden, Status) VALUES (%s, %s, %s, %s, %s)",(idx_user,dat,zeit,sec,'d'))
			cursor.close()
			db.close()

		def buttong(self):
			db=MySQLdb.connect("*****","****","****","*****")
			cursor = db.cursor()
			#print stat,"was steht im stat"
			cursor.execute("UPDATE users SET status = 'g' WHERE idx = %s",(idx_user))
			cursor.execute("SELECT Status, Uhrzeit FROM Zeitstempel WHERE idx = %s AND Datum = %s AND Status = %s ORDER BY Sekunden DESC",(idx_user,dat,stat))
			row8 = cursor.fetchall()
			for row8 in cursor:
				statnew = row8[0]
				z1new = row8[1]
				if (row8 != 0):
					cursor.execute("INSERT INTO Arbeitszeit (idx, Datum, z1, z2, status) VALUES (%s, %s, %s, %s, %s)",(idx_user,dat,z1new,zeit,'A'))
					cursor.execute("DELETE FROM Zeitstempel WHERE status = %s AND Datum = %s AND idx = %s",(statnew,dat,idx_user))
			cursor.close()
			db.close()
		
		def run(self):
			r = 0
			#def statuse():
			db=MySQLdb.connect("*****","****","****","*****")
			cursor = db.cursor()
			### ein frame für user status korrektur ###
			self.statusframe = Frame(self.fenster, height = 440, bg = "#AAC4D3", relief = "flat", border = 2)
			self.statusframe.pack(fill='x', pady = "1")
### möglicherweise ist der statusframe zu viel
			### ein frame im statusframe für user ###
			self.userf = Frame(self.statusframe, bg = "#AAC4D3", relief = "sunken", border = 2)
			self.userf.pack(fill = 'x', side = LEFT)

			cursor.execute("SELECT idx, user, status, korrektur, name, Urlaubsanspruch, Resturlaub FROM users ORDER BY idx")
			
			r = 0
			for row13 in cursor:
				user = row13[1]
				stat = row13[2]
				korr = row13[3]
				name = row13[4]
		
				if (korr == 'k'):
					korr = "ZEITKORREKTUR"
						
				if (stat == 'g'):
					self.labuser = Label(self.userf, relief = RAISED, width = 15, height = 2, bg = "#AAC4D3", font = "Verdana 10 bold", text = name) .grid(row=r,column=0)
					self.labstat = Label(self.userf, relief=SUNKEN, width=12, height=2, bg="red", font = "Verdana 10 bold", text="gehen") .grid(row=r,column=1)
					self.labkorr = Label(self.userf, relief=SUNKEN, width=14, height=2, bg="#AAC4D3", font="Verdana 10 bold", fg="red", text=korr) .grid(row=r,column=2)
					self.butk = Button(self.userf, relief=RAISED, width=4, height=1, bg='green', text='kommen', command=self.buttonk).grid(row=r,column=3)
					r = r + 1 + 2 + 3 + 4 + 5 + 6 + 7
					print user,korr,""
				elif (stat == 'p'):
					self.labuser = Label(self.userf, relief=RAISED, width=15, height=2, bg="#AAC4D3", font = "Verdana 10 bold", text=name) .grid(row=r,column=0)
					self.labstat = Label(self.userf, relief=SUNKEN, width=12, height=2, bg="yellow", font = "Verdana 10 bold", text="Pause") .grid(row=r,column=1)
					self.labkorr = Label(self.userf, relief=SUNKEN, width=14, height=2, bg="#AAC4D3", font="Verdana 10 bold", fg="red", text=korr) .grid(row=r,column=2)
					self.butk = Button(self.userf, relief=RAISED, width=4, height=1, bg='green', text='kommen', command=self.buttonk).grid(row=r,column=3)
					r = r + 1 + 2 + 3 + 4 + 5 + 6 + 7
					print user,korr,"pause"
				elif (stat == 'd'):
					self.labuser = Label(self.userf, relief=RAISED, width=15, height=2, bg="#AAC4D3", font = "Verdana 10 bold", text=name) .grid(row=r,column=0)
					self.labstat = Label(self.userf, relief=SUNKEN, width=12, height=2, bg="yellow", font = "Verdana 10 bold", text="dienstgang") .grid(row=r,column=1)
					self.labkorr = Label(self.userf, relief=SUNKEN, width=14, height=2, bg="#AAC4D3", font="Verdana 10 bold", fg="red", text=korr) .grid(row=r,column=2)
					self.butk = Button(self.userf, relief=RAISED, width=4, height=1, bg='green', text='kommen', command=self.buttonk).grid(row=r,column=3)
					r = r + 1 + 2 + 3 + 4 + 5 + 6 + 7
					print user,korr,"dienstgang"
				elif (stat == 'm'):
					self.labuser = Label(self.userf, relief=RAISED, width=15, height=2, bg="#AAC4D3", font = "Verdana 10 bold", text=name) .grid(row=r,column=0)
					self.labstat = Label(self.userf, relief=SUNKEN, width=12, height=2, bg="yellow", font = "Verdana 10 bold", text="mittag") .grid(row=r,column=1)
					self.labkorr = Label(self.userf, relief=SUNKEN, width=14, height=2, bg="#AAC4D3", font="Verdana 10 bold", fg="red", text=korr) .grid(row=r,column=2)
					self.butk = Button(self.userf, relief=RAISED, width=4, height=1, bg='green', text='kommen', command=self.buttonk).grid(row=r,column=3)
					r = r + 1 + 2 + 3 + 4 + 5 + 6 + 7
					print user,korr,"mittag"
				elif (stat == 'k'):
					self.labuser = Label(self.userf, relief=RAISED, width=15, height=2, bg="#AAC4D3", font = "Verdana 10 bold", text=name) .grid(row=r,column=0)
					self.labstat = Label(self.userf, relief=SUNKEN, width=12, height=2, bg="green", font = "Verdana 10 bold", text="anwesend") .grid(row=r,column=1)
					self.labkorr = Label(self.userf, relief=SUNKEN, width=14, height=2, bg="#AAC4D3", font="Verdana 10 bold", fg="red", text=korr) .grid(row=r,column=2)
					self.butp = Button(self.userf, relief=RAISED, width=2, height=1, bg='yellow', text='pause', command=self.buttonp).grid(row=r,column=4)
					self.butm = Button(self.userf, relief=RAISED, width=2, height=1, bg='yellow', text='mittag', command=self.buttonm).grid(row=r,column=5)
					self.butd = Button(self.userf, relief=RAISED, width=6, height=1, bg='yellow', text='dienstgang', command=self.buttond).grid(row=r,column=6)
					self.butg = Button(self.userf, relief=RAISED, width=2, height=1, bg='red', text='gehen', command=self.buttong).grid(row=r,column=7)
					r = r + 1 + 2 + 3 + 4 + 5 + 6 + 7
					print user,korr,"anwesend"
				elif (stat == '!'):
					self.labuser = Label(self.userf, relief=GROOVE, width=15, height=2, bg="#AAC4D3", font = "Verdana 9 bold", text=name) .grid(row=r,column=0)
					self.labkorr = Label(self.userf, relief=SUNKEN, width=14, height=2, bg="#AAC4D3", font="Verdana 9 bold", fg="red", text=korr) .grid(row=r,column=1)
					r = r + 1 + 2 + 3 + 4 + 5 + 6 + 7
					print user,korr,""

			cursor.close()
			db.close()
			 
			#self.statusframe.after(2000, self.run)
			

			self.tick()
			self.fenster.mainloop()

####### hier ist mein problem ich bekomme den update nicht hin
		def updateGUI(self):
				a = b # hier nichts
			#self.fenster.after(1000, self.updateGUI)
			#msg = "Data is True" if data else "Data is False"
			#self.lbl["text"] = msg
			#self.fenster.update()
			#self.lbl.after(1000, self.updateGUI)
			#self.run.after(2000, updateGUI)
			

		def tick(self):
			global time1
			self.time2 = time.strftime('%H:%M:%S')
			if self.time2 != time1:
				time1 = self.time2
				self.clock.config(text=self.time2)
			self.clock.after(1000, self.tick)

		def __init__(self):
			self.fenster = Tk()
			#self.lbl = Label(self.fenster, text="")
			title = self.fenster.title('ZEITERFASSUNG')
			self.fenster.geometry("657x520+24+10")
			self.fenster.configure(background='#AAC4D3')
			
			### Frame oben datum und Uhrzeit
			self.datzeit = Frame(self.fenster, width = 655, bg="green", relief = "sunken", border=2)
			self.datzeit.pack(fill='x', pady = "1")
			self.labdat = Label(self.datzeit, relief = GROOVE, bg = "white", font = "Verdana 10 bold", text = dat) #.grid(row = 0,column = 0, padx = 150)
			self.labdat.pack(side = RIGHT)
			self.clock = Label(self.datzeit, width=10, relief = GROOVE, bg = "white", font = "Verdana 10 bold")
			self.clock.pack(side = RIGHT)#side=LEFT
			
			### Frame unten Alarm
			self.alarm = Frame(self.fenster, width = 657, height=50, bg = "yellow", relief = "sunken", border=2)
			self.alarm.pack(fill='x',side=BOTTOM)
			self.labalarm = Label(self.alarm, relief = RAISED, width = 15, height = 2, bg = "#AAC4D3", font = "Verdana 10 bold", text = "Alarmanlage") 
			self.labalarm.pack(side=LEFT)
			self.butaus = Button(self.alarm, relief = RAISED, width = 3, height = 2, bg = 'red', text = "aus", command = aus) 
			self.butaus.pack(side=RIGHT)
			self.butan = Button(self.alarm, relief = RAISED, width = 3, height = 2, bg = 'green', text = 'an', command = an)
			self.butan.pack(side=RIGHT)
			
			self.updateGUI()

	if __name__ == "__main__":
		Gui().run()
Zuletzt geändert von Anonymous am Mittwoch 3. Dezember 2014, 10:17, insgesamt 2-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
BlackJack

@ganja: Als erstes solltest Du mal die Programmlogik von der GUI trennen. So verwoben wie das ist läuft das auf neuschreiben hinaus.

Dann bitte mit besseren Namen. Kein Abkürzungen in Namen verwenden die nicht allgemein bekannt sind, keine willkürlichen Zahlen an Namen anhängen (`row8`?), nur eine Sprache verwenden, also nicht `zeit` und `time1` in der gleichen Schleife. Das alleine ist schon verwirrend, dass es `sec`, `zeit1`, und `ts` gibt, die auch alle irgendwie für ”Zeit” stehen kann doch kein Mensch mehr auseinander halten.

Sternchenimporte sollte man sein lassen. Der übliche Weg Tkinter zu importieren steht doch sogar auskommentiert im Quelltext unter dem Sternchenimport.

Statt kryptischer Buchstabenkürzel die in einem Kommentar erklärt werden, sollte man Namen verwenden welche die Bedeutung auch überall im Programm kenntlich machen ohne das man den Kommentar suchen muss. '!'. 'g', 'p', und so weiter sind also Kandidaten für Konstanten oder `Enum` (gibt es für Python 2 als Backport unter dem Namen `enum34` im Python-Package Index).

Eine Endlosschleife und eine GUI-Anwendung vertragen sich so nicht. Die Schleife die das Programm am laufen hält ist die Hauptschleife des GUI-Toolkits, die in der `mainloop()`-Methode steckt.

Die Einrücktiefe ist per Konvention vier Leerzeichen pro Ebene.

Alle möglichen Namen am Anfang eines Blockes zu definieren, einige dann auch noch mit dem Hinweis/Kommentar ``#wird später benötigt`` ist unschön. Man sollte Namen erst definieren wenn sie auch tatsächlich benötigt werden. Sonst verteilt man Code der eigentlich zusammengehört über grössere Quelltextabschnitte, was das Programm schwerer lesbar und verstehbar macht und ausserdem wird das herausziehen von Funktionen aus zu gross gewordenen Quelltextabschnitten dadurch unnötig erschwert.

Zeichenketten sind keine Kommentare. Es keinen Sinn Zeichenketten mit in das Programm zu übernehmen die überhaupt keinen Effekt haben, ausser das sie im übersetzten Programm Platz wegnehmen.

Dateien die man öffnet, sollte man auch explizit wieder schliessen, und sich nicht auf die automatische Speicherverwaltung verlassen. Wann und ob die das Dateiobjekt abräumt und dabei schliesst, ist nicht garantiert. So etwas kann zu schwer zu findenen Fehlern oder dem aufbrauchen aller Dateihandles für einen Prozess führen.

Werte niemals nicht per Hand in Zeichenketten mit SQL-Anweisungen einfügen. Dafür verwendet man Platzhalter und überlässt das dem Datenbankmodul. Stichwort ist SQL-Injection.

Die Kombination `fetchall()` und dort dann den Rückgabewert einfach zu ignorieren und *danach* dann über das Cursor-Objekt zu iterieren macht keinen Sinn. Ich bin sogar überrascht dass das überhaupt funktioniert und nach der `fetchall()`-Methode der Cursor nicht bereits hinter dem letzten Datensatz steht.

Die GUI-Klasse in der Schleife zu definieren macht keinen Sinn. Da würd bei jedem Schleifendurchlauf eine neue Klasse erzeugt, die sich nicht von der Klasse unterscheidet die im letzten Durchlauf erzeugt wurde.

Die `__init__()`-Methode sollte als erstes in einer Klassendefinition stehen. Die vermittelt dem Leser welche Attribute es auf den Objekten gibt, deshalb sollte man die nicht erst lange suchen müssen. Ausserhalb der `__init__` sollten aus genau dem Grund auch keine neuen Attribute erstellt werden. Nachdem diese Methode durchlaufen wurde, sollte sich das Objekt in einem definierten und benutzbaren Zustand befinden.

Statt der Verknüpfung mit ``or`` beim testen ob der selbe Name einen von mehreren Werten hat, kann man eine kürzere Formulierung mit dem ``in``-Operator verwenden: ``if stat in ['p', 'm', 'd']:`` anstelle von ``if stat == 'p' or stat == 'm' or stat == 'd':``.

Bei ``if`` & Co sind keine Klammern um den gesamten Bedingungsausdruck nötig. Das liest sich komisch.

Die ganzen `button*`-Methoden enthalten teilweise identischen oder leicht unterschiedlichen Quelltext den man bestimmt besser auf Funktionen oder Methoden aufteilen kann. Die Namen der Methoden sich schlecht, weil man dazu die Bedeutung des jeweiligen, einbuchstabigen Namenssuffix kennen muss.

Die erste Zuweisung an `r` in `run()` wird nicht benutzt.

``r = r + 1 + 2 + 3 + 4 + 5 + 6 + 7``‽ Was soll das denn? Warum nicht einfach ``r += 1``. Oder `r` gar nicht manuell hochzählen sondern das in der Schleife mit der `enumerate()`-Funktion erledigen.

Bei den ganzen ``elif``\s dort fehl am Ende ein ``else``. Auch falls `stat` eigentlich keinen anderen Wert annehmen dürfte, möchte man den Fall dass das *doch* passiert, behandeln. Es passieren nämlich erstaunlich oft Dinge die eigentlich gar nicht passieren dürften, und darüber sollte man informiert werden.

``global`` solltest Du ganz schnell wieder vergessen. Insbesondere in einer Methode macht das keinen Sinn, denn Klassen sind ja gerade der Weg um modulglobale Namen für Werte loszuwerden. Wobei sich mir der Sinn hier auch gar nicht erschliesst warum man sich die vorherige Zeitangabe überhaupt global merken muss‽

Auf Modulebene sollten nur Konstanten, Funktionen, und Klassen definiert werden. Daraus folgt auch, dass das Hauptprogramm in einer Funktion verschwindet.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Vielen Dank für die ganzen hinweise, ich habe mir schon gedacht das es besser und einfacher geht, leider wußte ich es nicht besser, werde dann wohl noch mal anfangen und es besser und einfacher machen.

Danke noch einmal
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

ich habe versucht mein code anzupassen, leider feht es mir an kentniss, um das alles umzusetzten was BlackJack moniert hat. Auch wenn mein code nicht richtig profesionell ist, es tut, jeden tag lernt man dazu und irgendwann bin ich so weit das ich alles umzusetzten kann, was BlackJack moniert hat. Im Moment ist mir wichtig das sich das fenster alle 2 secunden aktualisiert und das bekomme ich nicht hin.

BlackJack --> Die Einrücktiefe ist per Konvention vier Leerzeichen pro Ebene.
Das weiß ich aber ich weis nicht wie ich hier im Forum das Aktivieren kann.

Hier nochmal mein code, verbesserungs vorschläge von BlackJack (aber nicht alles umgesetzt,da zu wenig erfahrung und kentniss)

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-


#test 08.10.2014
# Zeitkorrektur = !
# Abwesend = g
# Pause = p
# Mittag=m
# Arbeit = k

import MySQLdb
import sys
import ftplib
import time
import datetime
import os
import subprocess
from subprocess import Popen, PIPE, STDOUT
#from Tkinter import *
import Tkinter as tk



#while True:
#data = True
ts = time.time()
sec = int(ts)
dat = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d')
zeit = datetime.datetime.fromtimestamp(ts).strftime('%H:%M:%S')
zeit1 = datetime.datetime.fromtimestamp(ts).strftime('%H')
aus = 0
an = 0
b = 0
	
"""verbindung zu DB localhost """
db=MySQLdb.connect(".....",".....",".....","........")
#verbindung zu richtigen db
#db=MySQLdb.connect (".......",".......",".....","........")
#"""steht verbindung, wenn ja dann weiter"""
#"""if (db):
#       print "alles ok!"
#       else:
#               print "etwas stimmt nicht!" """
#       """etwas aus db auslesen"""
cursor = db.cursor()

###das hier wird raus kommen wenn test erfolgreich
rfidnr = open("/home/...").read()
query = "SELECT idx, status FROM users WHERE RFID = '" + (rfidnr) + "'"
cursor.execute(query)
werda = cursor.fetchall()
for row0 in cursor:
	idx_user = row0[0]
	stat = row0[1]

###dafür kommt das hier rein, muss aber noch getestet werden
########### hier wird die rfidnr vom rfid_control ausgelesen ########### 2
#def rfid_nr():
#	rfid = subprocess.Popen("/home/....", shell=False, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True).stdout.read()
#	rfidnr = rfid[:-1]
#	msa = "SELECT idx, status FROM users WHERE RFID = '" + (rfidnr) + "'"
#	cursor.execute(msa)
#	row = cursor.fetchall()
#	for row in cursor:
#		idx_user = row[0]
#      		stat = row[1]
#	
#		#if (idx_user != 0):
#		#	subprocess.Popen("/home/...../userbutton.py")

class Gui(object):
	def __init__(self):
		self.fenster = tk.Tk()
		#self.lbl = Label(self.fenster, text="")
		title = self.fenster.title('ZEITERFASSUNG')
		self.fenster.geometry("657x520+24+10")
		self.fenster.configure(background='#AAC4D3')
		
		### Frame oben datum und Uhrzeit
		self.datzeit = Frame(self.fenster, width = 655, bg="green", relief = "sunken", border=2)
		self.datzeit.pack(fill='x', pady = "1")
		self.labdat = Label(self.datzeit, relief = GROOVE, bg = "white", font = "Verdana 10 bold", text = dat) #.grid(row = 0,column = 0, padx = 150)
		self.labdat.pack(side = RIGHT)
		self.clock = Label(self.datzeit, width=10, relief = GROOVE, bg = "white", font = "Verdana 10 bold")
		self.clock.pack(side = RIGHT)#side=LEFT

		### Frame unten Alarm
		self.alarm = Frame(self.fenster, width = 657, height=50, bg = "yellow", relief = "sunken", border=2)
		self.alarm.pack(fill='x',side=BOTTOM)
		self.labalarm = Label(self.alarm, relief = RAISED, width = 15, height = 2, bg = "#AAC4D3", font = "Verdana 10 bold", text = "Alarmanlage") 
		self.labalarm.pack(side=LEFT)
		self.butaus = Button(self.alarm, relief = RAISED, width = 3, height = 2, bg = 'red', text = "aus", command = aus) 
		self.butaus.pack(side=RIGHT)
		self.butan = Button(self.alarm, relief = RAISED, width = 3, height = 2, bg = 'green', text = 'an', command = an)
		self.butan.pack(side=RIGHT)

		self.updateGUI()

	### wird noch für die alarmanlage benoetigt, ist aktiv?
	def an(self):
		self.butan.config(text='An')
	### wird noch für die alarmanlage benoetigt, ist nicht aktiv?
	def aus(self):
		self.butaus.config(text='Aus')
		
	### definition buttons ###
	def kommen(self):
		db=MySQLdb.connect("...","...","......",".....")
		cursor = db.cursor()
		stat = "SELECT idx, status FROM users WHERE RFID = '" + (rfidnr) + "'"
		cursor.execute(stat)
		row = cursor.fetchall()
		for row0 in cursor:
			idx_user = row0[0]
			stat = row0[1]

		if stat in ['g', '']:
		#if (stat == 'g' or stat == ''):
			cursor.execute("UPDATE users SET status='k' WHERE idx = %s",(idx_user))
			cursor.execute("INSERT INTO Zeitstempel (idx, Datum, Uhrzeit, Sekunden, Status) VALUES (%s, %s, %s, %s, %s)",(idx_user,dat,zeit,sec,'k'))
		elif stat in ['p', 'm', 'd']:
		#elif (stat == 'p' or stat == 'm' or stat == 'd'):
			cursor.execute("UPDATE users SET status='k' WHERE idx = %s",(idx_user))
			cursor.execute("SELECT status, Uhrzeit FROM Zeitstempel WHERE idx = %s AND Datum = %s AND Status = %s Order by Sekunden DESC",(idx_user,dat,stat))
			row5 = cursor.fetchall()
			for row5 in cursor:
				z1 = row5[1]
				statn = row5[0]
				if z1 != 0:
					cursor.execute("INSERT INTO Arbeitszeit (idx, Datum, z1, z2, status) VALUES (%s, %s, %s, %s, %s)",(idx_user,dat,z1,zeit,statn))
					cursor.execute("DELETE FROM Zeitstempel WHERE idx = %s AND status = %s AND Datum = %s",(idx_user,statn,dat))
		cursor.close()
		db.close()

	def pause(self):
		db=MySQLdb.connect("...",".....","....","....")
		cursor = db.cursor()
		cursor.execute("""UPDATE users SET status = 'p' WHERE idx = %s""",(idx_user))
		cursor.execute("""INSERT INTO Zeitstempel (idx, Datum, Uhrzeit, Sekunden, Status) VALUES (%s, %s, %s, %s, %s)""",(idx_user,dat,zeit,sec,'p'))
		cursor.close()
		db.close()

	def mittag(self):
		db=MySQLdb.connect("...",".....","....","....")
		cursor = db.cursor()
		cursor.execute("UPDATE users SET status = 'm' WHERE idx = %s",(idx_user))
		cursor.execute("INSERT INTO Zeitstempel (idx, Datum, Uhrzeit, Sekunden, Status) VALUES (%s, %s, %s, %s, %s)",(idx_user,dat,zeit,sec,'m'))
		cursor.close()
		db.close()

	def dienstgang(self):
		db=MySQLdb.connect("...",".....","....","....")
		cursor = db.cursor()
		cursor.execute("UPDATE users SET status = 'd' WHERE idx = %s", (idx_user))
		cursor.execute("INSERT INTO Zeitstempel (idx, Datum, Uhrzeit, Sekunden, Status) VALUES (%s, %s, %s, %s, %s)",(idx_user,dat,zeit,sec,'d'))
		cursor.close()
		db.close()

	def gehen(self):
		db=MySQLdb.connect("...",".....","....","....")
		cursor = db.cursor()
		#print stat,"was steht im stat"
		cursor.execute("UPDATE users SET status = 'g' WHERE idx = %s",(idx_user))
		cursor.execute("SELECT Status, Uhrzeit FROM Zeitstempel WHERE idx = %s AND Datum = %s AND Status = %s ORDER BY Sekunden DESC",(idx_user,dat,stat))
		row8 = cursor.fetchall()
		for row8 in cursor:
			statnew = row8[0]
			z1new = row8[1]
			if (row8 != 0):
				cursor.execute("INSERT INTO Arbeitszeit (idx, Datum, z1, z2, status) VALUES (%s, %s, %s, %s, %s)",(idx_user,dat,z1new,zeit,'A'))
				cursor.execute("DELETE FROM Zeitstempel WHERE status = %s AND Datum = %s AND idx = %s",(statnew,dat,idx_user))
		cursor.close()
		db.close()
		
	def run(self):
		r = 0
		#def statuse():
		db=MySQLdb.connect("...",".....","....","....")
		cursor = db.cursor()
		
		### ein frame für users status  ###
		#self.statusframe = Frame(self.fenster, height = 440, bg = "#AAC4D3", relief = "flat", border = 2)
		#self.statusframe.pack(fill='x', pady = "1")

		### ein frame im statusframe für user ###
		self.userf = Frame(self.fenster, bg = "#AAC4D3", relief = "sunken", border = 2)
		self.userf.pack(fill = 'x', side = LEFT)

		cursor.execute("SELECT idx, user, status, korrektur, name, Urlaubsanspruch, Resturlaub FROM users ORDER BY idx")

		for row13 in cursor:
			user = row13[1]
			stat = row13[2]
			korr = row13[3]
			name = row13[4]

			if korr == 'k' :
				korr = "ZEITKORREKTUR"

			if stat == 'g' :
				self.labuser = Label(self.userf, relief = RAISED, width = 15, height = 2, bg = "#AAC4D3", font = "Verdana 10 bold", text = name) .grid(row=r,column=0)
				self.labstat = Label(self.userf, relief=SUNKEN, width=12, height=2, bg="red", font = "Verdana 10 bold", text="gehen") .grid(row=r,column=1)
				self.labkorr = Label(self.userf, relief=SUNKEN, width=14, height=2, bg="#AAC4D3", font="Verdana 10 bold", fg="red", text=korr) .grid(row=r,column=2)
				self.butk = Button(self.userf, relief=RAISED, width=4, height=1, bg='green', text='kommen', command=self.kommen).grid(row=r,column=3)
				r += 1
				#r = r + 1 + 2 + 3 + 4 + 5 + 6 + 7
				print user,korr,""
			elif stat == 'p' :
				self.labuser = Label(self.userf, relief=RAISED, width=15, height=2, bg="#AAC4D3", font = "Verdana 10 bold", text=name) .grid(row=r,column=0)
				self.labstat = Label(self.userf, relief=SUNKEN, width=12, height=2, bg="yellow", font = "Verdana 10 bold", text="Pause") .grid(row=r,column=1)
				self.labkorr = Label(self.userf, relief=SUNKEN, width=14, height=2, bg="#AAC4D3", font="Verdana 10 bold", fg="red", text=korr) .grid(row=r,column=2)
				self.butk = Button(self.userf, relief=RAISED, width=4, height=1, bg='green', text='kommen', command=self.kommen).grid(row=r,column=3)
				r += 1
				#r = r + 1 + 2 + 3 + 4 + 5 + 6 + 7
				print user,korr,"pause"
			elif stat == 'd' :
				self.labuser = Label(self.userf, relief=RAISED, width=15, height=2, bg="#AAC4D3", font = "Verdana 10 bold", text=name) .grid(row=r,column=0)
				self.labstat = Label(self.userf, relief=SUNKEN, width=12, height=2, bg="yellow", font = "Verdana 10 bold", text="dienstgang") .grid(row=r,column=1)
				self.labkorr = Label(self.userf, relief=SUNKEN, width=14, height=2, bg="#AAC4D3", font="Verdana 10 bold", fg="red", text=korr) .grid(row=r,column=2)
				self.butk = Button(self.userf, relief=RAISED, width=4, height=1, bg='green', text='kommen', command=self.kommen).grid(row=r,column=3)
				r += 1
				#r = r + 1 + 2 + 3 + 4 + 5 + 6 + 7
				print user,korr,"dienstgang"
			elif stat == 'm' :
				self.labuser = Label(self.userf, relief=RAISED, width=15, height=2, bg="#AAC4D3", font = "Verdana 10 bold", text=name) .grid(row=r,column=0)
				self.labstat = Label(self.userf, relief=SUNKEN, width=12, height=2, bg="yellow", font = "Verdana 10 bold", text="mittag") .grid(row=r,column=1)
				self.labkorr = Label(self.userf, relief=SUNKEN, width=14, height=2, bg="#AAC4D3", font="Verdana 10 bold", fg="red", text=korr) .grid(row=r,column=2)
				self.butk = Button(self.userf, relief=RAISED, width=4, height=1, bg='green', text='kommen', command=self.kommen).grid(row=r,column=3)
				r += 1
				#r = r + 1 + 2 + 3 + 4 + 5 + 6 + 7
				print user,korr,"mittag"
			elif stat == 'k' :
				self.labuser = Label(self.userf, relief=RAISED, width=15, height=2, bg="#AAC4D3", font = "Verdana 10 bold", text=name) .grid(row=r,column=0)
				self.labstat = Label(self.userf, relief=SUNKEN, width=12, height=2, bg="green", font = "Verdana 10 bold", text="anwesend") .grid(row=r,column=1)
				self.labkorr = Label(self.userf, relief=SUNKEN, width=14, height=2, bg="#AAC4D3", font="Verdana 10 bold", fg="red", text=korr) .grid(row=r,column=2)
				self.butp = Button(self.userf, relief=RAISED, width=2, height=1, bg='yellow', text='pause', command=self.pause).grid(row=r,column=4)
				self.butm = Button(self.userf, relief=RAISED, width=2, height=1, bg='yellow', text='mittag', command=self.mittag).grid(row=r,column=5)
				self.butd = Button(self.userf, relief=RAISED, width=6, height=1, bg='yellow', text='dienstgang', command=self.dienstgang).grid(row=r,column=6)
				self.butg = Button(self.userf, relief=RAISED, width=2, height=1, bg='red', text='gehen', command=self.gehen).grid(row=r,column=7)
				r += 1
				#r = r + 1 + 2 + 3 + 4 + 5 + 6 + 7
				print user,korr,"anwesend"
			elif stat == '!' :
				self.labuser = Label(self.userf, relief=GROOVE, width=15, height=2, bg="#AAC4D3", font = "Verdana 9 bold", text=name) .grid(row=r,column=0)
				self.labkorr = Label(self.userf, relief=SUNKEN, width=14, height=2, bg="#AAC4D3", font="Verdana 9 bold", fg="red", text=korr) .grid(row=r,column=1)
				r += 1
				#r = r + 1 + 2 + 3 + 4 + 5 + 6 + 7
				print user,korr,""
			else :
				print "etwas ist total falsch"

		cursor.close()
		db.close()
			 
		#self.userf.after(2000, self.run)
			
		self.tick()
		self.fenster.mainloop()

	### mein problem wie mache ich ein update des Fensters oder Frame oder buttons und Labels
	def updateGUI(self):
		a = b
		#self.fenster.after(1000, self.updateGUI)
		#msg = "Data is True" if data else "Data is False"
		#self.lbl["text"] = msg
		#self.fenster.update()
		#self.lbl.after(1000, self.updateGUI)
		#self.run.after(2000, updateGUI)

	def tick(self):
		global zeit
		self.time2 = time.strftime('%H:%M:%S')
		if self.time2 != zeit:
			zeit = self.time2
			self.clock.config(text=self.time2)
		self.clock.after(1000, self.tick)

if __name__ == "__main__":
	Gui().run()
ps. wie mach ich das das der code richtig eingerückt gezeigt wird, im vorschau wird es richtig angezeigt, doch bei absenden ist dan alles unlesbar.
Zuletzt geändert von ganja am Mittwoch 3. Dezember 2014, 16:00, insgesamt 2-mal geändert.
BlackJack

@ganja: Die Einrücktiefe von vier Leerzeichen ist nichts was man hier im Forum aktivieren kann, die müssen in Deinem Quelltext stehen. Das stellt man also irgendwo in dem Editor ein, mit dem man den Quelltext schreibt.

In der Vorschau sieht man das gleiche wie hinterher im geposteten Beitrag. Die Vorschau ist nicht das Texteingabefeld wo man den Beitragstext hinein schreibt. Für Quelltext gibt es Code-Tags und dafür auch eine Schaltfläche im Beitragseditor über dem Textfeld ('Code') und eine Dropdown-Liste wo man die Sprache für die Syntaxeinfärbung auswählen kann (Standard: „Python”).

Um die GUI zu aktualisieren, musst Du Dir die Widget-Objekte die verändert werden können/sollen als Attribute merken und das dann halt einfach machen. Und das würde man dann auch für das erste Anzeigen aller Daten die aktualisiert werden sollen schon in der Methode machen und nicht vorher schon mal woanders. Dann hätte man da nämlich Code doppelt. Also in der `__init__()` alle Anzeigeelemente erstellen und dort die Veränderbaren noch *nicht* mit Werten füllen, sondern das erst in der `update_gui()`-Methode tun.

Eine saubere Trennung von Programmlogik und GUI und damit auch den Daten und der Anzeige der Daten würde die Sache IMHO einfacher machen. Und auch eine feinere Aufteilung als *eine* GUI-Klasse.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Vielen Dank das du dich beteiligst.
Leider verstehe ich nicht ganz, was du meinst.

BlackJack
Um die GUI zu aktualisieren, musst Du Dir die Widget-Objekte die verändert werden können/sollen als Attribute merken und das dann halt einfach machen. Und das würde man dann auch für das erste Anzeigen aller Daten die aktualisiert werden sollen schon in der Methode machen und nicht vorher schon mal woanders. Dann hätte man da nämlich Code doppelt. Also in der `__init__()` alle Anzeigeelemente erstellen und dort die Veränderbaren noch *nicht* mit Werten füllen, sondern das erst in der `update_gui()`-Methode tun.

muss dann weiter probieren, ich weis für jemanden der Profi ist sieht mein code und mein Problem lächerlich, aber wenn ich es könnte würde ich nicht nach hilfe fragen.

Trodtztem Vielen Dank
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

BlackJack hat geschrieben:@ganja: Die Einrücktiefe von vier Leerzeichen ist nichts was man hier im Forum aktivieren kann, die müssen in Deinem Quelltext stehen. Das stellt man also irgendwo in dem Editor ein, mit dem man den Quelltext schreibt.

In der Vorschau sieht man das gleiche wie hinterher im geposteten Beitrag. Die Vorschau ist nicht das Texteingabefeld wo man den Beitragstext hinein schreibt. Für Quelltext gibt es Code-Tags und dafür auch eine Schaltfläche im Beitragseditor über dem Textfeld ('Code') und eine Dropdown-Liste wo man die Sprache für die Syntaxeinfärbung auswählen kann (Standard: „Python”).

Um die GUI zu aktualisieren, musst Du Dir die Widget-Objekte die verändert werden können/sollen als Attribute merken und das dann halt einfach machen. Und das würde man dann auch für das erste Anzeigen aller Daten die aktualisiert werden sollen schon in der Methode machen und nicht vorher schon mal woanders. Dann hätte man da nämlich Code doppelt. Also in der `__init__()` alle Anzeigeelemente erstellen und dort die Veränderbaren noch *nicht* mit Werten füllen, sondern das erst in der `update_gui()`-Methode tun.

Eine saubere Trennung von Programmlogik und GUI und damit auch den Daten und der Anzeige der Daten würde die Sache IMHO einfacher machen. Und auch eine feinere Aufteilung als *eine* GUI-Klasse.



Ich danke dir nochmal BlackJack ich habs hinbekommen. Noch nicht ganz wie ich es möchte aber die widgets aktualisieren alle 2 sec.

Vielen dank für deine hinweise.

Gruß
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@ganja: Du hast nicht wirklich an 9 verschiedenen Stellen die Zugangsdaten zu Deiner Datenbank explizit hingeschrieben? Wieviel Aufwand ist es, wenn sich mal der Server oder das Passwort ändert, das zu korrigieren und keine Stelle zu übersehen? Ein erster Schritt wäre es, diese Daten in Konstanten am Anfang des Programms zu sammeln, ein weiterer, die Verbindung zur Datenbank in einer Funktion zu kapseln.
In Zeile 50 und 111 wird immer noch ein SQL-Befehl von Hand zusammengebaut. Wenn das Ergebnis nur ein Datensatz ist, dann verwendet man nicht fetchall und eine for-Schleife sondern fetchone. Irgendwie wird an beiden Stellen das selbe gemacht, sowas gehört in eine Funktion.
Durch was unterscheiden sich "pause", "mittag" und "dienstgang"? Das läßt sich alles in einer Funktion zusammenfassen.
Wann ist die Bedingung in Zeile 170 nicht erfüllt?
Ab Zeile 200, durch was unterscheiden sich die if-Zweige stat='d', 'p', 'g' und 'm'. Weißt Du eigentlich, was Du an labuser, labkorr usw. bindest?
Wenn Du einen Zeilenzähler brauchst, dann zählt man nicht von Hand und erst recht nicht in jedem if-Zeig einzeln, sondern benutzt enumerate.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Doch Sirius3 das habe ich so gemacht, ich weiß das es nicht gut ist, jetzt da meine buttons und labels sich aktualisieren jetzt möchte ich das alle ändern ich bin absolut deiner meinung es braucht nur eimal ein zugang zu DB, das muß ich jetzt versuchen zu machen. Vielen Dank das ihr mir hinweise gibt für die stellen die nicht ok sind in meinem code, das mein code einfache werden muss ist mir klar, aber nochmal in diesem augenblick in diesem Moment ist das mein kenntnisstand, deswegen bin euch dankbar für jeden hinweis.

Sirius3
Durch was unterscheiden sich "pause", "mittag" und "dienstgang"? Das läßt sich alles in einer Funktion zusammenfassen.
Nur durch den eintrag in der DB p,m,d.

Danke

Gruß
Antworten