[英]How can I update Tkinter label from a spawned process (multiprocessing.Process)?
Summary: In Python when I update a Tkinter label text from a spawned process, the label on the GUI is not updated, although the spawned process is executed. 我怎樣才能讓它從生成的進程中更新?
我正在 Lubuntu 20.04 中使用 Python 2.7.2
編輯:我也嘗試使用 Python 3.8,必須額外安裝 python3-tk,更改一些語法(打印命令后的括號並將 Tkinter 替換為 tkinter),但問題仍然看起來相同。 結束編輯
這是我的示例代碼,可以獨立試用:
from Tkinter import *
from multiprocessing import Process
# simple Label change invoked from "simple" button
def bnAction_sync():
print "bnAction_sync"
changeLabel()
print "bnAction_sync done"
# asynchronous label change invoked from Async button
def bnAction_async():
print "bnAction_async"
p = Process(target=changeLabel)
p.start()
print "bnAction_Async done"
def changeLabel():
print "change label"
lbl['text'] = "Text changed"
### Apr 19 2021:
### uncommenting the following line really updates label but makes program crash ###
# root.update_idletasks
print "change label done"
root = Tk()
btnSync = Button(root, text="simple", command=bnAction_sync)
btnSync.pack()
btnAsync = Button(root, text="async", command=bnAction_async)
btnAsync.pack()
lbl = Label(root, text="Initial text")
lbl.pack()
root.mainloop()
如果我按下“簡單”按鈕,文本會在 label 中更新。 都好。
但是:如果我按下“異步”按鈕,
我想這樣做的原因是:因為我正在啟動一個長時間運行的衍生進程,之后我想更新 label。 然而,所有其他進程應該並行運行。 所以我創建了一個 function f,其中包含長時間運行的 function 和 label71 依次更新 ZC1C425268E68385CAF11。 我想異步調用 f 。 所以原則上:
def longprocess():
code...
def updatelabel_after_longprocess():
code...
def f():
longprocess()
updatelabel_after_longprocess()
p = Process(target=f)
p.start()
do other things immediately
在我讀到的某個地方,刷新被暫停,而腳本仍在運行。 我嘗試了一些 p.join 插入,但沒有運氣。
請幫忙,謝謝!
您不太可能從另一個進程工作更新您的 label。 這可能是可能的,但它會非常復雜。 相反,我建議您創建一個線程,在另一個進程中啟動昂貴的代碼,然后等待更新 GUI,直到該進程完成:
from multiprocessing import Process
from threading import Thread
def longprocess():
# do whatever you need here, it can take a long time
def updatelabel_after_longprocess():
# do whatever GUI stuff you need here, this will be run in the main process
def thread_helper():
process = Process(target=longprocess)
process.start()
process.join() # this waits for the process to end
updatelabel_after_longprocess()
if __name__ == "__main__":
t = Thread(target=thread_helper)
t.start()
# do whatever else you have to do in parallel here
t.join()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.