zeit different

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

Hallo,
dein Beispiel @BlackJack ist perfekt, leicht zu lesen und zu verstehen, ich habe versucht es an meine Bedürfnisse anzupassen, vielleicht habe ich es falsch gemacht

Code: Alles auswählen

def __init__(self):
	self.start_time = None
	#######
	self.elapsed_time = ('0' + str(TimeDelta())) 
	#######
	#hier möchte ich 00:00:00 ausgabe und nicht 0:00:00, ist das der richtige weg um das zu erreichen
	
def stop(self):
	self.elapsed_time = DateTime.utcnow() - self.start_time
	######
	self.elapsed_time = str(self.elapsed_time) #test
	self.elapsed_time = self.elapsed_time[2:10] #test
	######
	#hier auch, ich möchte nur 2 letzte zahlen von den mili oder micro secunden haben, da bin ich mir auch nicht sicher ob das 
	#der richtige weg ist, zumindest macht es genau das was ich will, vielleicht kann man es noch eleganter hin bekommen
	
	self.start_time = None
	#print(self.elapsed_time)
	#print('stop')
	
#hier würde ich gerne um ein reset erweitern 
def reset(self):
	self.elapsed_time = '00:00:00'
	self.start_time = None
	#print('reset')

#hier bekomme ich problem, da immer reset 
def toggle(self):
	if self.is_running:
		self.stop()
	else:
	#elif self.is_running:
		self.start()
	#else:
	#	self.reset()
	
#hier scheitere ich an der erweiterung des reset
def update_display(self):
	self.display['text'] = self.stopwatch
	self.toggle_button['text'] = (
		'Stop' if self.stopwatch.is_running else 'Start'
		###'Stop' if self.stopwatch.is_running elif self.stopwatch.is_running 'Start' else 'Reset'###
		#  not gibt es nicht?
	)

#ich würde gerne button raus nehmen und das ganze an tastatur eingabe (es sollte mit irgend einer taste gehen, zb. taste s 1x gedrückt = start, taste s zum zweiten mal stop, taste s zum dritten mal reset) dran verknüpfen, ist so etwas möglich?

class StopwatchUI(tk.Frame):
	#@staticmethod
	#def s_Key(event):
	#	print (event + " key pressed")

	#@staticmethod
	#def d_Key(event):
	#	print (event + " key pressed")

# bei def main habe ich noch, aber im moment geht es noch nicht 

#root.bind('<s>', s_Key)
#root.bind('<d>', d_Key)
#root.focus_set()
Danke

Gruß
ganja
Zuletzt geändert von Anonymous am Sonntag 15. Mai 2016, 14:20, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@ganja: TimeDelta bietet nicht so komfortable Formatierungsmethoden an, wie es z.B. DateTime tut. Das heißt, Du mußt das selbst machen. Aber statt überall elapsed_time in einen String zu konvertieren, bietet es sich an, nur die __str__-Methode von Stopwatch zu ändern:
Z.B. so:

Code: Alles auswählen

    def __str__(self):
        seconds = self.elapsed_time.total_seconds()
        minutes, seconds = divmod(seconds, 60)
        hours, minutes = divmod(minutes, 60)
        return '{0:02.0f}:{1:02.0f}:{2:05.2f}'.format(hours, minutes, seconds)

    def reset(self):
       self.elapsed_time = TimeDelta()
       self.start_time = None
Für einen Three-State-Button brauchst Du auch eine Variable, die 3 Zustände annehmen kann. is_running hat nur zwei:

Code: Alles auswählen

    def update_display(self):
        self.display['text'] = self.stopwatch
        self.toggle_button['text'] = (
            'Stop' if self.stopwatch.is_running else
            'Reset' if self.stopwatch.elapsed_time else 'Start'
        )
 
    def do_toggle(self):
        if self.stopwatch.is_running:
            self.stopwatch.stop()
        elif self.stopwatch.elapsed_time:
            self.stopwatch.reset()
        else:
            self.stopwatch.start()
        self.update_display()
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Hallo @Sirius3, vielen Dank es funktioniert, ist es möglich geht das überhaupt, das ich anstatt Button Tastatur benutze, das ist mein versuch, aber leider ohne Erfolg, irgendetwas übersehe ich im Moment da fehlt noch was, versuche ich heute Nachmittag nochmal.
Noch einmal Vielen Dank @Sirius3

Code: Alles auswählen

def s_Key(self, event):
	self.start_time = DateTime.utcnow()
	print(self.elapsed_time)
		print (event + " key pressed")

def d_Key(self,event):
	self.elapsed_time = DateTime.utcnow() - self.start_time
	self.start_time = None
	print(self.elapsed_time)
	print (event + " key pressed")
	
def r_Key(self,event):
	self.elapsed_time = TimeDelta()
	self.start_time = None
	print (event + " key pressed")
	
##im main habe dann das hinzugefügt
def main():
	root.bind('<s>', s_Key)
	root.bind('<d>', d_Key)
	root.bind('<r>', d_Key)
	root.focus_set()
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@ganja: das geht, wenn Du die Bindings richtig in die StopwatchUI-Klasse integrierst.
BlackJack

Wobei: Wenn der eine Button den es momentan gibt, den Fokus hat, dann kann man den auch ohne irgendwas spezielles zu tun mit der Leertaste ”klicken”. Das ist die Tk-Standardbindung für Schaltflächen.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Hallo,

Danke @Sirius3, das werde ich dann versuchen, ich möchte das man den Button gar nicht sieht.

Danke @BlackJack, das habe ich nicht gewusst das man auch Leertaste benutzen kann, muss ich auf einem anderem Rechner probieren auf meinem geht es nicht, wenn das mit der Leertaste klappt, kann ich irgendwie den Button unsichtbar machen geht so etwas.

Da wo der Button im Moment ist möchte ich eine liste mit 10 Ergebnisen wer am nächsten dran war, und ich denke ohne Button sieht es besser aus, vielleicht kaufe ich noch irgend einen Drücker, dann soll es mit dem Drücker gehen.

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

Hallo,
Ich brauche ein wenig Unterstützung falls jemand Lust/zeit/etc hat.
Mein vorhaben habe ich dank @BlackJack und @Sirius3 fast geschafft, ich kann jetzt mit der taste starten stoppen und Reset ausführen d.h den Button benutzen, Ich möchte jetzt den Button entfernen und nur mit der taste starten stoppen Reset ausführen, dafür müsste ich 'def update_display(self):' anpassen denke ich, daran scheitere ich aber im Moment, das 'def do_toggle(self):' würde ich dann nicht mehr brauchen da das 'def s_Key(self, event):' übernimmt, oder liege ich komplett falsch?

Würde mich wirklich freuen falls jemand zeit hat, und mir einen Tipp oder Beispiel geben könnte.
Danke

Code: Alles auswählen

class StopwatchUI(tk.Frame):

	#self.frame.bind("<s>",self.do_toggle)
	#self.frame.pack()
		
	self.toggle_button = tk.Button(parent, command=self.do_toggle)
	self.toggle_button.pack(side=tk.TOP)
		
	self.update_display()
		
	parent.bind('<s>', self.s_Key)

#@staticmethod
def s_Key(self, event):
	if self.stopwatch.is_running:
		self.stopwatch.stop()
	elif self.stopwatch.elapsed_time:
		self.stopwatch.reset()
	else:
		self.stopwatch.start()
	self.update_display()
		
def update_display(self):
	self.display['text'] = self.stopwatch
	self.toggle_button['text'] = (
		'Stop' if self.stopwatch.is_running else
		'Reset' if self.stopwatch.elapsed_time else 'Start'
	)

def do_toggle(self):
	if self.stopwatch.is_running:
		self.stopwatch.stop()
	elif self.stopwatch.elapsed_time:
		self.stopwatch.reset()
	else:
		self.stopwatch.start()
	self.update_display()
     
def main():
	root = tk.Tk()
	root.title('Zeit stoppen')
	root.configure(background='#008A34')
	root.geometry("1020x815+0+0")
	root.focus_set() ### ist das hier richtig (bei recherche habe ich das in vielen bs. gesehen)
	ui = StopwatchUI(root, Stopwatch())
	ui.pack()
	root.mainloop()

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

Leute ich habe es hin bekommen mit 'pack_forget' bei Button, leider bin ich mir nicht sicher ob das der richtige weg ist, aber es tut
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

hallo,
könntet ihr mir noch mal helfen, ich versuche die Differenz von zb . 10sec - gestoppte zeit in einem label anzuzeigen im moment schaffe ich das nicht, des weiteren versuche ich die Differenz in ein liste zu speichern, aber da tut es auch nicht so wie es soll, es wird nur ein Eintrag gespeichert beim nächstem mal wird mir der Eintrag überschrieben, ich dachte das jedes mal ein neuer Eintrag in die liste rein geschrieben wird fortlaufend Ohne den anderen zu überschreiben zb.
0:00:03.50
0:00:02.65
usw.

Die liste lese ich dann aus und möchte 10 beste die am nächsten an der vorgabe sind möchte ich anzeigen, das scheitert im moment auch, ich lese die liste es wird aber nur die letzte zeit angezeigt und das 10x, irgend etwas habe ich nicht richtig, ich glaube es wäre besser wenn ich das anzeigen der liste auch an stop() anbinde, jedes mal wenn stop gedrückt wird soll die liste aktualisiert werden, wäre das besser?
hier der code

Code: Alles auswählen

def stop(self):
	self.elapsed_time = DateTime.utcnow() - self.start_time
	self.start_time = None
	rounden = TimeDelta(0,0,010000)
	self.ergebnis = TimeDelta(0,5,0)
	self.erg = self.ergebnis - self.elapsed_time
	self.erg = self.erg + rounden
	#print ('nach rou' ,self.erg)
	self.erg = str(self.erg)
	self.erg = self.erg[:10]
	print('zum ersten ',self.erg)
	self.write_list()

def reset(self):
	self.elapsed_time = TimeDelta()
	self.start_time = None

#ich habe mir gedacht jedes mal wenn stop gedrückt wird, wird in die liste geschrieben
def write_list(self):
	if self.erg:
		with open('ergebnise.txt', 'w') as f:
			f.write(self.erg)
			# + "\n"
			del self.erg
		f.closed

class StopwatchUI(tk.Frame):
def get_erg(self):
	self.liste = ''
	with open('/ergebnise.txt', 'r') as f:
		for line in f:
			self.liste = line
			print('1111111111', self.liste)
	return self.liste

def update_erg(self):
	erg = ''
	for widget in self.get_erg_widgets:
		widget.destroy()
	self.get_erg_widgets = list()
	
	for erg in self.get_erg():
	#for column, text in enumerate([erg]):
		print('koliko ', self.liste)
		label = tk.Label(self.frame1, text=self.liste, justify=tk.LEFT, font="bold", bg='red',width=50)
		label.pack()
		self.get_erg_widgets.append(label)
	self.frame1.after(2000, self.update_erg)
Zuletzt geändert von Anonymous am Mittwoch 1. Juni 2016, 17:18, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

wie kann ich meinen Beitrag bearbeiten? Die Anbindung an stop() habe ich hin bekommen, nur noch das auslesen und speichern bekomme ich nicht hin
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@ganja: Deine StopWatch-Klasse macht hier meiner Meinung nach zu viel. Das Sammeln von Ergebnissen wäre besser in Deiner GUI-Klasse aufgehoben, und dann dort in einer Liste, statt in einer Datei. Was Du da genau mit ergebnis und erg machst ist mir auch unklar. Jedenfalls sollten das keine Attribute sein. Das zeigt sich auch daran, dass Du versuchst in write_list auf self.erg zuzugreifen und es danach löschst. Dateien die mit "w" geöffnet werden, werden neu erstellt, der alte Inhalt also gelöscht. "a" hängt dagegen ans Ende der Datei an. Was bezweckst Du mit der Zeile "f.closed"?
In get_erg ist liste keine Liste und sollte auch kein Attribut sein. Wenn ich die letzten 10 Ergebnisse darstellen wollte, würde ich die Labels einmal erzeugen und alle 2 Sekunden nur den Inhalt ändern, statt sie jedesmal neu zu erzeugen.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Hallo Sirius3,
Vielen Dank, für die Tipps ich habe es fast geschafft, habe noch ein kleines Problem ich bekomme nicht die 10 Ergebnis die am nächstem der vorgabe sind z.b. 10 sec. Die Datei ist im Moment leichter für mich wie eine liste um zusetzen da mir noch Erfahrung fehlt. ich probiere teste und wenn es geht und ich verstehe was ich tue dann ist ok fürs erste. Vielen Dank für den Tipp mit 'a'. Wenn ich es alle 2 sec mit after Update dann habe ich in dem frame1 kurze Aussetzer, deshalb habe ich gedacht wenn stopp dann Update, so habe ich es auch im Moment am laufen.
hier ein bsp. so sieht meine Datei aus:
0:00:02.30
0:00:04.40
0:00:00.50
0:00:04.40
0:00:04.21
0:00:03.95
0:00:04.45
0:00:04.10
0:00:04.15
0:00:03.10
0:00:04.56
0:00:03.05
0:00:03.39
0:00:02.87
0:00:04.14
0:00:04.27
usw

Code: Alles auswählen

class Stopwatch(object):
	def stop(self):
	#das sieht nicht gut aus es geht wahrscheinlich besser, das self.erg liefert mir 6 zeichen hinter punkt, ich möchte 2 und dann 	habe ich versucht probiert, es tut aber wenn man die vorgabe überschreitet bekomme ich -1 tag .... zurück, das muss ich noch ändern
		
		self.elapsed_time = DateTime.utcnow() - self.start_time
		self.start_time = None
		rounden = TimeDelta(0,0,010000)
		self.ergebnis = TimeDelta(0,10,0)
		self.erg = self.ergebnis - self.elapsed_time
		self.erg = self.erg + rounden
		#print ('nach rou' ,self.erg)
		self.erg = str(self.erg)
		self.erg = self.erg[:10]
		#print('zum ersten ',self.erg)
		self.write_list()

	def write_list(self):
		if self.erg:
		with open('ergebnise.txt', 'a') as f:
			f.write(self.erg + "\n")
			
class StopwatchUI(tk.Frame):
	def get_erg(self):
		self.liste = ''
		with open('/home/ja/Downloads/sa_stika/python/vom_raspi/zeiterfassung/ergebnise.txt', 'r') as f:
			for line in f:
				self.liste = line
				print('1111111111', self.liste)
			return (self.liste)

	def update_erg(self):
		#print ('22222' , self.liste)
		erg = ''
		for widget in self.get_erg_widgets:
			widget.destroy()
		self.get_erg_widgets = list()
		
		for erg in self.get_erg():
			for column, text in enumerate([erg]):
				view = sorted(erg)
				#print ('tztuztutuztuztuztuzttuz',view)
				for text in view:
					#print('koliko ', self.liste)
					label = tk.Label(self.frame1, text=self.liste, justify=tk.LEFT, font="bold", bg='#AAC4D3',width=50)
					label.pack()
					self.get_erg_widgets.append(label)
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Hallo,
hier mit bekomme ich die ausgabe,

Code: Alles auswählen

def update_erg(self):
	#print ('22222' , self.liste)
	erg = ''
	for widget in self.get_erg_widgets:
		widget.destroy()
	self.get_erg_widgets = list()

	for row_number,(erg) in enumerate(self.get_erg()):
		#for column_number , text in enumerate([erg]):
		view = sorted(self.liste)
		#print ('1111111111111111111111111111111111 ',view)
		for text in view[0:10]:
			#print('koliko ', self.liste)
			label = tk.Label(self.frame2, text=text, justify=tk.LEFT, font="bold", bg='white',width=50)
			label.pack()
			self.get_erg_widgets.append(label)
	#self.frame1.after(2000, self.update_erg)
leider um so größer die datei wird um so langsamer wird meine gui und wenn ich die vorgegeben zeit überschreite bekomme ich
'-1 day, 23' als Ergebnis zurück. Habt ihr ein Tipp für mich wie löse ich die 2 Probleme damit wir anfangen können zu spielen.
Danke im Voraus
Zuletzt geändert von Anonymous am Freitag 3. Juni 2016, 14:37, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@ganja: warum hast Du da zwei verschachtelte for-Schleifen? Was ist self.liste und warum wird die mehrfach sortiert? Wie ich schon vor zwei Wochen geschrieben habe, solltest Du am besten Deine TimeDelta selbst in einen String verwandeln, dann kannst Du negative Zeiten auch so darstellen, wie Du es möchtest.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Hallo Sirius3, die verschachtelte for schleife hatte ich übersehen, habe es jetzt geändert, versuche deinen Tipp zu befolgen aber ich scheitere, ich glaube die Berechnung mache ich total falsch, es muss einen einfacheren weg geben, aber mir fällt nichts anders im Moment ein. kann es sein das in den strings einmal : und deswegen es nicht geht, nur damit ich es verstehe.

Code: Alles auswählen

def stop(self):
	self.elapsed_time = DateTime.utcnow() - self.start_time
	self.start_time = None
	self.elapsed_time = str(self.elapsed_time) #test
	self.elapsed_time = self.elapsed_time[2:10] #test
	print('self.elapsed_time',self.elapsed_time)
		
	rounden = TimeDelta(0,0,010000)
	self.ergebnis = TimeDelta(0,5,0)
	print('self.ergebnis',self.ergebnis)
	self.erg = self.ergebnis - self.elapsed_time 
	
	# hier scheitere ich, TypeError: unsupported operand type(s) for -: 'datetime.timedelta' and 'str', ist auch irgend wie logisch, wenn ich aber string - string mache geht es auch nicht, TypeError: unsupported operand type(s) for -: 'str' and 'str'
	
	##self.erg = self.erg + rounden
	##self.erg = str(self.erg)
	##self.erg = self.erg[:10]
	##print('zum ersten ',self.erg)
	#print('stop',self.elapsed_time)
	#vorgabe = TimeDelta(0,5,0)
	#self.erg = vorgabe - self.elapsed_time
	#print('ttttttttt ',self.erg)
	##self.write_list()
BlackJack

@ganja: Was sollte denn dabei heraus kommen wenn man zwei Zeichenketten voneinander abzieht? Es müssen natürlich Zeitobjekte sein, denn die wissen wie sie voneinander subtrahiert werden.
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

hallo BlackJack, ich hoffe das ich es jetzt verstanden habe, erst nach der Berechnung in string umwandeln, oder erst dann wenn die Label gefüllt werden.
Vielen Dank
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

Hallo,
Bitte nicht Lachen, ich bekomme es nicht hin, wenn man die Vorgabe überschreitet, ich weiß das ihr Profis seid und das ihr das im kleinen Finger habt, im Moment bin ich am verzweifeln ich sehe von lauter Bäume den Wald nicht, und wenn ich es mir jetzt so anschaue was ich da mache das ist so kompliziert für mich geworden, vielleicht habt ihr kurz zeit und Lust mir zu Helfen.

Code: Alles auswählen

def stop(self):
	self.elapsed_time = DateTime.utcnow() - self.start_time
	self.start_time = None
	rounden = TimeDelta(0,0,010000)
	self.ergebnis = TimeDelta(0,5,0)
	self.erg = self.ergebnis - self.elapsed_time
	print('self.erg',self.erg)
	self.erg = self.erg + rounden
	#print ('nach rou' ,self.erg)
	self.erg = str(self.erg)
	#self.erg = self.erg[8:22]
	print('2222333 self.erg',self.erg)
	
	if self.erg[0] == '0': 
		self.erg = self.erg[:10]
		self.erg = self.erg + ' zu schnell'
		print('00000zum ersten ',self.erg)
		#hier ist oben ist alles ok, wenn man unter der vorgabe ist wird halt die fehlende zeit angezeigt und dazu noch 'zu schnell'
		#hier unten fangen meine probleme an, wenn man die zeit überschritten hat bekomme ich zurück '-1 day, 23:59:56.960928' dann schaue ich wenn '-' dann mache ich ein string nur mit der zeit z.b '23:59:55.87', ich denke ich muß jetzt den string wieder in etwas umwandeln womit ich rechnen kann, ich dachte 24:00:00.00 - 23:59:56.96 (bestimmt gibt es einfachere Berechnung, die kenne ich aber nicht, und zu wenig Erfahrung und kenntnis)  dann habe ich mein ergebnis, dabei scheitere ich im Augenblick.
	if self.erg[0] == '-':
		#self.erg = self.erg[8:19]
		#self.erg = TimeDelta(self.erg)
		print(' selferg nach', self.erg)
		self.erg = vorgabe2 - self.erg
		self.erg = self.erg + ' zu schnell'
	self.write_list()
Zuletzt geändert von Anonymous am Sonntag 5. Juni 2016, 16:45, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@ganja: das was Du hier in die `stop`-Methode schreibst gehört da nicht hin, weil es nichts mit dem stoppen einer Stopuhr zu tun hat.

Generell sieht kann man Dein Problem so lösen:

Code: Alles auswählen

TARGET_TIME = TimeDelta(seconds=5)
NULL_DELTA = TimeDelta(0)
EPS_DELTA = TimeDelta(seconds=0.01)

[...]
difference = stopwatch.elapsed_time - TARGET_TIME
if abs(difference) < EPS_DELTA:
    print("Getroffen!")
elif difference < NULL_DELTA:
    print("Zu langsam um {}".format(abs(difference))
else:
    print("Zu schnell um {}".format(abs(difference))
ganja
User
Beiträge: 189
Registriert: Mittwoch 3. Dezember 2014, 07:44

hallo Sirius3, Vielen Dank, ich dachte mir schon das es viel einfacher gehen muss als ich das versucht habe(du hast 10 zeilen code und ich habe 20, danke das du deine Erfahrung und dein wissen teilst), ich habe es in stop() drin da ich dachte das es an dieser stelle richtig ist, ich weiss leider nicht wo der richtige platz dafür wäre als stop da ich das Ergebnis in die Datei speichern will.
Vielen Dank, ich probiere mal
Antworten