簡體   English   中英

如何從衍生的進程(multiprocessing.Process)更新 Tkinter label?

[英]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 文本更新行。
  • 但是:這是我的問題: GUI 上的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM