¿Cómo paro tkinter después de la función?

Estoy teniendo problemas para detener el ‘feed’; El argumento de cancelación no parece tener ningún impacto en el método posterior. Aunque “feed se detuvo” se imprime en la consola.

Estoy intentando tener un botón que iniciará la alimentación y otro que detendrá la alimentación.

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() 

Con la salida:

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

El problema es que, aunque está llamando a print_sleep con True para detener el ciclo, ya hay un trabajo pendiente a la espera de ser despedido. Al presionar el botón de parada no se activará un nuevo trabajo, pero el trabajo anterior todavía está allí, y cuando se llama a sí mismo, pasa a Falso, lo que hace que el ciclo continúe.

Debe cancelar el trabajo pendiente para que no se ejecute. Por ejemplo:

 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) 

Nota: asegúrese de inicializar self._job algún lugar, como en el constructor de su objeto de aplicación.

Cuando llama a root.after(...) , devolverá un identificador. Debe hacer un seguimiento de ese identificador (por ejemplo, almacenarlo en una variable de instancia), y luego puede llamar a root.after_cancel(after_id) para cancelarlo.