2012-03-19 12 views
6

Mam problem z zatrzymaniem "kanału"; Argument cancel nie wydaje się mieć żadnego wpływu na metodę after. Chociaż "feed stopped" jest drukowany na konsoli.Jak zatrzymać tkinter po funkcji?

Próbuję mieć jeden przycisk, który uruchomi kanał, a drugi zatrzyma kanał.

from Tkinter import Tk, Button 
import random 

    def goodbye_world(): 
     print "Stopping Feed" 
     button.configure(text = "Start Feed", command=hello_world) 
     print_sleep(True) 

    def hello_world(): 
     print "Starting Feed" 
     button.configure(text = "Stop Feed", command=goodbye_world) 
     print_sleep() 

    def print_sleep(cancel=False): 
     if cancel==False: 
      foo = random.randint(4000,7500) 
      print "Sleeping", foo 
      root.after(foo,print_sleep) 
     else: 
      print "Feed Stopped" 


    root = Tk() 
    button = Button(root, text="Start Feed", command=hello_world) 

    button.pack() 


    root.mainloop() 

z wyjściem:

Starting Feed 
Sleeping 4195 
Sleeping 4634 
Sleeping 6591 
Sleeping 7074 
Stopping Feed 
Sleeping 4908 
Feed Stopped 
Sleeping 6892 
Sleeping 5605 
+0

Nie jestem całkowicie pewien, jak działa tkinter, ale wygląda mi to jak wątek. Jeśli anulujesz (wątek bezpieczny) globalnie, czy to rozwiąże problem? – mklauber

+0

@mklauber: nie, nie jest to wątek. Tkinter jest jednowątkowy. –

+0

@BryanOakley: Dzięki. Dlatego opublikowałem jako komentarz. Nie byłem pewien, więc chciałem tylko zadać pytanie. – mklauber

Odpowiedz

13

Problem polega na tym, że mimo wywołania print_sleep z True, aby zatrzymać cykl, czeka już na niego oczekująca praca. Naciśnięcie przycisku zatrzymania nie spowoduje uruchomienia nowej pracy, ale stara praca nadal istnieje, a kiedy sama się wywołuje, przechodzi w False, co powoduje kontynuację pętli.

Musisz anulować oczekujące zlecenie, aby go nie uruchomić. Na przykład:

def cancel(): 
    if self._job is not None: 
     root.after_cancel(self._job) 
     self._job = None 

def goodbye_world(): 
    print "Stopping Feed" 
    cancel() 
    button.configure(text = "Start Feed", command=hello_world) 

def hello_world(): 
    print "Starting Feed" 
    button.configure(text = "Stop Feed", command=goodbye_world) 
    print_sleep() 

def print_sleep(): 
    foo = random.randint(4000,7500) 
    print "Sleeping", foo 
    self._job = root.after(foo,print_sleep) 

Uwaga: upewnij się zainicjować self._job gdzieś, tak jak w konstruktorze obiektu swojej aplikacji.

13

Po wywołaniu root.after(...), zwróci identyfikator. Powinieneś śledzić ten identyfikator (np. Przechowywać go w zmiennej instancji), a następnie możesz później zadzwonić pod numer root.after_cancel(after_id), aby go anulować.

Powiązane problemy