Stoppuhr

Fragen zu Tkinter.
Antworten
pythonstarter
User
Beiträge: 53
Registriert: Donnerstag 15. April 2010, 20:34

Hallo, wollte mal eine Stoppuhr in tkinter basteln, komme aber grad nicht weiter. Da hab ich einen Hänger.

Code: Alles auswählen

import tkinter as tk, time

main = tk.Tk()

def uhr():
    label = tk.Label(main, text = "")
    label.pack()
    second = 0
    while second < 60:
        label.configure(text = second)
        second +=  1
        time.sleep(1)
    
button = tk.Button(main, text = "Stopuhr - Start", command = uhr)
button.pack()

main.mainloop()

Hat jemand einen Tipp - ist sicher mal wieder ganz einfach und ich komm ´nicht drauf :oops:
problembär

time.sleep() blockiert Dein gesamtes GUI. Du suchst tkrootwidget.after(). Guckstu hier.

Gruß
pythonstarter
User
Beiträge: 53
Registriert: Donnerstag 15. April 2010, 20:34

und wie und wo bau ich das in mein script ein`?
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

pythonstarter hat geschrieben:und wie und wo bau ich das in mein script ein`?
Gar nicht. - Wenn das Programm nichts anderes tun soll als sichtbar zu zählen, dann genügt ein
label.update() nach dem label.configure(...).

Die after()-Methode solltest du dir trotzdem mal zu Gemüte führen.
pythonstarter
User
Beiträge: 53
Registriert: Donnerstag 15. April 2010, 20:34

man möge mir verzeihen - - - ich komm nicht weiter.
könnte mir mal jemand die funktion mal in mein script einbauen? das wäre echt super
Dankeschön.
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

In Dein Script kann ichs' Dir nicht einbauen, nur zeigen, wie ich das gemacht habe:

Code: Alles auswählen

import Tkinter as tk

class Gui(object):


  def __init__(self, counter):

    self.root = tk.Tk()
    self.counter = counter
    self.ivar = tk.IntVar()
    self.ivar.set(counter)
    self.label = tk.Label(textvariable=self.ivar, width=2, font=('ARIAL', 200, 'bold'))
    self.label.pack()

    self.count()

    
  def count(self, speed=1000):

    self.counter -= 1
    if self.counter >= 0:
      self.ivar.set(self.counter)
      self.root.after(speed, self.count)     
    else:
      self.root.quit()
    
      
  def run(self):
    
    self.root.mainloop()


if __name__ == '__main__':

  Gui(12).run()
:wink:
yipyip
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

pythonstarter hat geschrieben:man möge mir verzeihen - - - ich komm nicht weiter.
könnte mir mal jemand die funktion mal in mein script einbauen? das wäre echt super
Dankeschön.
Hä? Ich hab dir doch genau beschrieben, was du machen musst!
Also, wenn dir das nicht reicht, dann solltest du vielleicht einmal mit den Basics beginnen und die GUI-Programmierung vorerst hintenanstellen.
problembär

pythonstarter hat geschrieben:könnte mir mal jemand die funktion mal in mein script einbauen?
Ja:

Code: Alles auswählen

#!/usr/bin/env python
#-*- coding: iso-8859-1 -*-

import tkinter as tk

def uhr(main, label, second):

    if second <= 60:
        label.configure(text = str(second))
        second += 1
        main.after(1000, lambda: uhr(main, label, second))
   
main = tk.Tk()
label = tk.Label(main, text = "")
label.pack()
button = tk.Button(main, text = "Stopuhr - Start", command = lambda: uhr(main, label, 0))
button.pack()
main.mainloop()
Warum glaubst Du mir nicht, daß sowas besser mit OOP zu lösen ist?
Dann brauchst Du nämlich nicht all diese Argumente mit zu übergeben.

Gruß
BlackJack

Wobei bei den ganzen Beispielen weder `time.sleep()` noch `after()` harte Garantien über die verstrichene Zeit machen. Mit jeder Sekunde addieren sich da also eventuell bis wahrscheinlich Fehler. Man sollte `after()` nur als Auslöser für eine Aktualisierung verwenden und die tatsächliche Zeit aus der Systemzeit ermitteln.

Edit: @problembär: `main` schleppst Du da eigentlich nur als Argument mit um `after()` darauf aufzurufen -- die Methode gibt es aber auf jedem Widget. `label` müsste also ausreichen.
pythonstarter
User
Beiträge: 53
Registriert: Donnerstag 15. April 2010, 20:34

Hi problembär,
vielen Dank. :)
und natürlich auch an die anderen.
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

@pythonstarter: Hier nochmal eine "richtige" Stoppuhr:
http://paste.pocoo.org/show/263224/
bzw.
http://www.python-forum.de/pastebin.php?mode=view&s=70
:wink:
yipyip
problembär

BlackJack hat geschrieben:Wobei bei den ganzen Beispielen weder `time.sleep()` noch `after()` harte Garantien über die verstrichene Zeit machen. Mit jeder Sekunde addieren sich da also eventuell bis wahrscheinlich Fehler. Man sollte `after()` nur als Auslöser für eine Aktualisierung verwenden und die tatsächliche Zeit aus der Systemzeit ermitteln.
Ja, hab' ich beim Schreiben auch schon dran gedacht.
BlackJack hat geschrieben:Edit: @problembär: `main` schleppst Du da eigentlich nur als Argument mit um `after()` darauf aufzurufen -- die Methode gibt es aber auf jedem Widget. `label` müsste also ausreichen.
Auch das stimmt. Allerdings hab' ich mal mit ".bind()" einige Tasten an Buttons oder Canvases gebunden. Das hat dazu geführt, daß die Tasten nur dann gingen, wenn das jeweilige Widget den Fokus hatte (was nicht gewollt war). Seitdem lege ich so globale Sachen am liebsten auf das main-Widget.

Gruß
Antworten