2012-03-19 105 views
6

我遇到了阻止'feed'的问题;取消参数似乎对after方法没有任何影响。尽管“馈送停止”被打印到控制台。如何在功能后停止tkinter?

我试图有一个按钮,将开始饲料和另一个将停止饲料。

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

随着输出:

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

我不完全确定tkinter是如何工作的,但这看起来像是一个线程问题。如果您取消全局(线程安全),那么这是否可以解决问题? – mklauber 2012-03-19 19:46:12

+0

@mklauber:不,不是线程问题。 Tkinter是单线程的。 – 2012-03-19 20:31:40

+0

@BryanOakley:谢谢。这就是我作为评论发布的原因。我不确定,所以我只是想提出这个问题。 – mklauber 2012-03-19 20:33:04

回答

13

的问题是,即使你打电话print_sleepTrue停止循环,不过已经有了暂挂作业等待开火。按下停止按钮不会导致新的作业启动,但旧作业仍然存在,并且当它自己调用时,它会通过False导致循环继续。

您需要取消挂起的作业,以便它不运行。例如:

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) 

注意:确保你初始化self._job的地方,比如在你的应用程序对象的构造函数。

13

当你调用root.after(...),它会返回一个标识符。您应该跟踪该标识符(例如,将其存储在实例变量中),然后您可以稍后致电root.after_cancel(after_id)来取消它。