2016-03-25 8 views
0

Ich versuche, ein Programm zu machen, wenn es beginnt, ein GUI-Fenster angezeigt wird, und es gibt einen Countdown von 5 bis 0.Mein Countdown-Programm funktioniert nicht gut

Dies ist der Code:

number=5 
from tkinter import * 
class application(Frame): 
    def __init__(self, master): 
    Frame.__init__(self, master) 
    self.grid() 
    self.create_widget() 
    def create_widget(self): 
    global number 
    self.lbl1=Label(self, text=number) 
    self.lbl1.grid(row=0, column=0, sticky=W) 
    for I in range(5): 
     number=number-1 #the countdown 
     root.after(1000, self.update) 
    def update(self): 
    global number 
    self.lbl1.configure(text=number) 

Wenn das Programm startet, die Zahl 5 erscheint, und schaltet sich plötzlich auf 0

Kann mir jemand sagen, was das Problem in meinem Code ist?

+0

Es ist kein Problem. Ihre 'for'-Schleife läuft sehr schnell (innerhalb von Millisekunden), so dass Sie die Label-Aktualisierung nicht wirklich sehen. – MattDMo

+0

Sie haben eine Klasse. Warum verwenden Sie eine globale Variable? – zondo

+0

Sie sollten die 'Zahl' in Ihrer' update' Methode verringern. Sie sollten die "for" -Schleife überhaupt nicht haben. Rufen Sie stattdessen 'root.after (1000, self.update)' einmal in 'create_widget' und einmal in' update' auf (so dass jedes 'update' eine Sekunde später ein' 'update' 'auslöst). Alternativ können Sie auch anrufen 'after' in einer' for'-Schleife, wie Sie es jetzt tun (abnehmende 'number' muss noch in' update' gehen), aber erhöhen Sie bei jedem Anruf die Zeit, um die es um 1 Sekunde warten wird . – ArtOfWarfare

Antwort

1

Sie erstellen 5 Update-Callbacks, die in 1 Sekunde ausgeführt werden. Alle 5 triggern und aktualisieren auf den Endwert der Zahl, die 0. Stelle print (Nummer) in den Callback um zu sehen.

Sie müssen einen Rückruf erstellen und bedingt einen anderen in der Update-Funktion erstellen. Die folgenden Läufe von einem IDLE-Editor oder in einem Terminal mit Python -m filename.py

from tkinter import * 

class application(Frame): 
    def __init__(self, master, number): 
     Frame.__init__(self, master) 
     self.master = master 
     self.number = number 
     self.grid() 
     self.create_widget() 
    def create_widget(self): 
     self.lbl1 = Label(self, text=self.number) 
     self.lbl1.grid(row=0, column=0, sticky=W) 
     self.master.after(1000, self.update) 
    def update(self): 
     if self.number: 
      self.number -= 1 
      self.lbl1.configure(text=self.number) 
      self.master.after(1000, self.update) 

root = Tk() 
number=5 
app = application(root, number) 

Es gibt viele andere Beispiele für korrekte Verwendung von root.after sind auf SO.

2

root.after(1000, self.update) tut nicht das Warten selbst. Es setzt self.update in eine Warteschlange, die die Hauptschleife später überprüft. Sie setzen self.update in eine Warteschlange und fahren dann mit der Schleife fort. Sie können I auf jede Nummer von 1 bis 5 vor dem .after(...) Anruf setzen, den Sie vorgenommen haben, als I Null wurde, wird wirksam. Statt I in der create_widget() Schleife Einstellung, setzen Sie es in update():

def create_widget(self): 
    ... 
    self.number = number 
    root.after(1000, self.update) 
def update(self): 
    self.lbl1.configure(text=self.number) 
    self.number -= 1 
    if self.number: 
     root.after(1000, self.update)