2015-08-23 201 views
0

下面的python代碼有一個TKinter gui,用於更新計算函數中的內容(在self.after()的末尾調用它自己,GUI也有一些滑塊,用戶將能夠調整參數,計算中存在睡眠延遲問題:代碼運行良好,除了time.sleep(1)阻塞的不僅僅是計算1秒,還包括GUI本身:只能每秒移動一次滑塊,然後所有東西都被阻塞一秒鐘。我能做些什麼time.sleep(1)只能讓計算函數進入睡眠狀態,而不是GUI本身?我需要運行計算函數在單獨的線程中?Tkinter with after and time.sleep

import Tkinter as tk 
import ttk 
import time 

class GUI(tk.Frame): 
    def __init__(self, master=None): 
     tk.Frame.__init__(self, master) 
     self.pack() 
     self.i=0 
     self.var1 = tk.StringVar() 
     self.var2 = tk.StringVar() 
     self.var3 = tk.StringVar() 
     self.var4 = tk.StringVar() 
     self.var5 = tk.StringVar() 
     self.var6 = tk.StringVar() 
     self.var7 = tk.StringVar() 
     tk.Label(self, textvariable=self.var1,justify='left').pack() 
     tk.Label(self, textvariable=self.var2).pack() 
     tk.Label(self, textvariable=self.var3).pack() 
     tk.Label(self, textvariable=self.var4).pack() 
     tk.Label(self, textvariable=self.var5).pack() 
     tk.Label(self, textvariable=self.var6).pack() 
     tk.Label(self, textvariable=self.var7).pack() 


     p1 = tk.Scale(master, from_=1, to=20, orient=tk.HORIZONTAL).pack() 
     p2 = tk.Scale(master, from_=1, to=20, orient=tk.HORIZONTAL).pack() 
     p3 = tk.Scale(master, from_=1, to=20, orient=tk.HORIZONTAL).pack() 
     p4 = tk.Scale(master, from_=1, to=20, orient=tk.HORIZONTAL).pack() 
     p5 = tk.Scale(master, from_=1, to=20, orient=tk.HORIZONTAL).pack() 

     self.progress = ttk.Progressbar(self, orient="horizontal",length=100, mode="determinate") 
     self.progress.pack() 

    def calculation(self): 
     # complex calculations that last 30 minutes in total 
     self.i += 1 
     time.sleep(1) 
     max=1000 
     self.var1.set("Value1: "+str(self.i)) 
     self.var2.set("Value2: "+str(self.i+100)) 
     self.var3.set("Value3: "+str(self.i+100)) 
     self.var4.set("Value4: "+str(self.i+100)) 
     self.var5.set("Value5: "+str(self.i+100)) 
     self.var6.set("Value6: "+str(self.i+100)) 
     self.var7.set("Value7: "+str(self.i+100)) 
     self.progress["value"] = int(round(self.i*100/max)) 
     #self.update() # no need, will be automatic as mainloop() runs 
     self.after(1, self.calculation) 

app=GUI() 
app.calculation() # start calculations 
app.mainloop() # run gui 
+1

爲什麼你需要'time.sleep(1)'?爲什麼你不能自己處理閒置的時間呢? –

+0

你需要update_idletasks .... –

+0

在這個例子中是的,但真正的代碼更復雜,睡眠是必要的 – Nickpick

回答

0

如果你絕對必須使用睡眠,那麼是的,計算應該在另一個線程或另一個進程中完成。

+0

是的,這是絕對必要的。此外,實際的生活計算將持續超過一分鐘。我是否會簡單地用一個線程調用mainloop,並用另一個線程來計算? – Nickpick

+0

@尼古拉斯:是的。您必須確保其他線程不會調用任何窗口小部件方法。您必須將結果放在隊列中,並讓gui線程從隊列中讀取結果。 –

+0

你有任何額外的信息,這個隊列系統如何工作?謝謝 – Nickpick