2011-09-21 38 views
1

我有一個已經很大Tkinter程序,讓我有一個初始化文件,其中定義了root = Tk()窗口(含基本上是Text小部件和其他一些東西),多了一些代碼,最後調用mainloop()功能。Tkinter:一個或多個主循環?

一切正常,直到我需要的mainloop之前調用過程,我想提出一個wait窗口的開始,在過程的結束時被銷燬。

我寫的是這樣的:

msg = Message(root, text='wait a few seconds...') 
msg.pack() 

不過,這並不而不能工作,因爲mainloop()還沒有被調用呢!

如果我不是這樣做:

msg = Message(root, text='wait a few seconds...') 
msg.pack() 
mainloop() 

程序停止在這個第一mainloop,未完成的過程調用。

mainloop()應該作爲你最後的程序行,在這之後的Tkinter程序的工作原理是通過用戶點擊和交互驅動的邏輯等

在這裏,我需要提高窗口的序列>做的東西>破壞窗口>主循環

回答

1

在程序初始化後,您無需調用mainloop一次。這對於啓動事件循環是必要的,這對於Windows自己繪製,響應事件等是必需的。

你可以做的是把你的初始化分成兩部分。第一個 - 創建等待窗口 - 發生在啓動事件循環之前。第二個 - 完成剩餘的初始化 - 發生在事件循環開始後。您可以通過after方法安排第二階段來完成此操作。

這裏有一個簡單的例子:

import Tkinter as tk 
import time 

class SampleApp(tk.Tk): 
    def __init__(self, *args, **kwargs): 

     # initialize Tkinter 
     tk.Tk.__init__(self, *args, **kwargs) 

     # hide main window 
     self.wm_withdraw() 

     # show "please wait..." window 
     self.wait = tk.Toplevel(self) 
     label = tk.Label(self.wait, text="Please wait...") 
     label.pack() 

     # schedule the rest of the initialization to happen 
     # after the event loop has started 
     self.after(100, self.init_phase_2) 

    def init_phase_2(self): 

     # simulate doing something... 
     time.sleep(10) 

     # we're done. Close the wait window, show the main window 
     self.wait.destroy() 
     self.wm_deiconify() 

app = SampleApp() 
app.mainloop() 
0

您應該使用Tkinter的方法來運行異步的循環函數,但是應該使用asyncore.poll(0)而不是asyncore.loop()。如果每x毫秒調用函數asyncore.poll(0),它將不再對Tkinter的主循環產生影響。

+0

因爲我告訴你,我是一個新手Tkinter的,所以我從來沒有聽說過asyncore ...我看到的文檔http://infohost.nmt.edu/ tcc/help/pubs/tkinter /不提及它,而我的最終資源(effbot)在這裏說了些什麼http://effbot.org/zone/asyncore.htm ...我寧願更容易些,我原來的問題沒有看起來很複雜,需要這樣的工作! – alessandro

+0

也許這可以解決您的問題:[點擊我!](http://stackoverflow.com/questions/459083/how-do-you-run-your-own-code-alongside-tkinters-event-loop ) – jermenkoo