2012-04-18 91 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來做到這一點,在嘗試使用線程之前應考慮嘗試使用該示例。線程化使得你想要的東西成爲可能,但它也使你的代碼變得更加複雜。