繁体   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