2013-04-04 100 views
1

我有以下代碼的部分的問題:延遲方法執行命令

my_var = tk.StringVar(value="start") 
my_label = tk.Label(self.root, textvariable=my_var) 
def my_method(input): 
    my_var.set("working") 
    #make a method call to an external Python API; can take a few mins to finish 
    my_var.set("complete") 

tk.Button(self.root, text="GO!", command=lambda: my_method(input)) 

我有一個按鈕,單擊時,應該執行my_method應該最初改變my_label文本working,在外部API中處理一些操作,然後將標籤更新爲complete。實際發生的是my_method被調用,標籤的文本不會改變,API調用需要幾分鐘,然後我的標籤更新爲complete。我假設它可以快速處理兩個設置命令,但我只能看到最終的設置值。

是否有這樣的事情發生的原因(我做錯了什麼),並有解決方案嗎?如果這是預期的行爲,有人可以解釋爲什麼是這樣嗎?

雖然寫這個,我想也許啓動一個線程來執行初始設置調用,看看是否會工作。我寧願更簡單的解決方案。

回答

3

Tkinter需要您立即從回調中返回,以便它可以回到Tk.mainloop中需要執行的處理。如果無法執行此處理,它將無法更新您的標籤文本。 (它也不能處理正常的處理事件,如拖動窗口等)

回調不應該長時間掛在主線程上,因此。如果爲他們做了一些耗時的處理,它應該在一個單獨的線程中完成。

+0

如果我創建了一個新線程來進行進程調用,那麼如何防止用戶在完成之前能夠與Tk進行交互?是否可以凍結主循環直到線程結束?實質上,我需要阻止進一步的用戶與GUI的交互,直到API調用完成。 – 2013-04-04 10:55:59

+2

不要凍結主循環;相反,您可以將按鈕狀態設置爲「DISABLED」,直到過程完成。對於按鈕'b',設置'b.config(state = DISABLED)'。然後當你完成後,將其設置回:'b.config(state = NORMAL)' – twasbrillig 2013-04-04 10:59:47

+0

謝謝,這當然是一個更好的方法。 – 2013-04-04 11:04:28