2012-04-18 92 views
3

我希望代码能够在后台运行并定期更新我的GUI。我怎样才能做到这一点?在Tkinter的背景下运行一个无限循环

例如,假设我想在GUI代码的后台执行这样的事情,你可以看到如下:

x = 0 

while True: 
    print(x) 
    x = x + 1 
    time.sleep(1) 

这是GUI代码:

class GUIFramework(Frame): 

    def __init__(self,master=None): 
     Frame.__init__(self,master) 
     self.master.title("Volume Monitor") 
     self.grid(padx=10, pady=10,sticky=N+S+E+W) 
     self.CreateWidgets() 

    def CreateWidgets(self): 
     textOne = Entry(self, width=2) 
     textOne.grid(row=1, column=0) 

     listbox = Listbox(self,relief=SUNKEN) 
     listbox.grid(row=5,rowspan=2,column=0,columnspan=4,sticky=N+W+S+E,pady=5) 
     listbox.insert(END,"This is an alert message.") 

if __name__ == "__main__": 
    guiFrame = GUIFramework() 
    guiFrame.mainloop() 

回答

5

这是一个很少有人不清楚你的代码应该做什么,但是,如果你只是想每秒调用一次函数(或者你想要的秒数),你可以使用after方法。

所以,如果你只想做一些事情textOne,你可能会做这样的事情:

... 
textOne = Entry(self, width=2) 
textOne.x = 0 

def increment_textOne(): 
    textOne.x += 1 

    # register "increment_textOne" to be called every 1 sec 
    self.after(1000, increment_textOne) 

你可以使此功能类的方法(在这种情况下,我把它叫做callback)和你的代码是这样的:

class Foo(Frame): 

    def __init__(self, master=None): 
     Frame.__init__(self, master) 
     self.x = 0 
     self.id = self.after(1000, self.callback) 

    def callback(self): 
     self.x += 1 
     print(self.x) 
     #You can cancel the call by doing "self.after_cancel(self.id)" 
     self.id = self.after(1000, self.callback) 

gui = Foo() 
gui.mainloop() 
2

如果你真的想运行你没有选择,只能使用一个单独的线程鲜明的无限循环,并通过一个线程安全的队列通信。但是,除非在相当罕见的情况下,否则不应该运行无限循环。完成后,您已经有一个无限循环运行:事件循环。所以,当你说你想要一个无限循环时,你真的会问如何在无限循环中做一个无限循环。

@mgilson给出了一个很好的示例,说明如何使用after来做到这一点,在尝试使用线程之前应考虑尝试使用该示例。线程化使得你想要的东西成为可能,但它也使你的代码变得更加复杂。