【问题标题】:Python multiprocessing and tkinter - how to connect this process (GUI and spawned process)?Python 多处理和 tkinter - 如何连接此进程(GUI 和衍生进程)?
【发布时间】:2015-11-29 06:32:12
【问题描述】:

很久以前我开始使用线程。我的 GUI 中任何功能的线程。但上次我专注于多处理模块。这里的问题是,当我生成新进程时,我不知道如何连接我的 GUI。 这是示例代码 - 一键“执行”线程,它按预期工作。 第二个按钮生成过程,但我的 GUI 未更新(输入字段未填充文本)。 如何解决? 如何从 Process 接收“打印”报表? 谢谢!

import tkinter as tk
import time
from multiprocessing import Process, Pool
from threading import Thread


root = tk.Tk()
inputEn = tk.Entry(root)
inputEn.pack()


def runner(txt):
    print("runner")
    time.sleep(5)
    # this doesn't work when I use it with Process
    inputEn.insert(0, "{}".format(txt))
    print("runner end")


def process():
    p = Process(target=runner, args=("process",))
    p.start()


def thread():
    p = Thread(target=runner, args=("thread",))
    p.start()



btnStart = tk.Button(root, text="Start Process", command=process)
btnStart.pack()

btnStart2 = tk.Button(root, text="Start Thread", command=thread)
btnStart2.pack()



if __name__=="__main__":
    root.mainloop()

【问题讨论】:

    标签: python multithreading user-interface tkinter


    【解决方案1】:

    当使用进程生成时,子进程不能更新父进程的变量。 您可以通过修改代码进行实验:

    inputEn.pack()
    globalv = 0
    
    def runner(txt):
        global globalv
        print("runner")
        time.sleep(5)
        # this doesn't work when I use it with Process
        inputEn.insert(0, "{}".format(txt))
        globalv = globalv + 1
        print 'globalv : ', globalv
    

    然后,当通过线程调用 runner 时,globalv 将被更新,当通过进程调用 runner 时不会更新。 您必须使用队列让孩子与您的应用程序交互。

    这是因为子进程是使用父进程上下文的副本实例化的 - 而线程使用与父进程相同的上下文。

    【讨论】:

      【解决方案2】:

      你没有说为什么这里需要多处理。如果你只想更新一个变量,tkinter 的 after() 可以很好地解决这个问题。一个不太优雅的例子

      import Tkinter as tk
      import random
      
      class UpdateLabel(object):
          def __init__(self, master):
              self.master=master
              self.str_var=tk.StringVar()
              self.str_var.set("start")
              tk.Entry(root, textvariable=self.str_var, width=50).pack()
      
              tk.Button(self.master, text="Exit", bg="orange",
                        command=self.master.quit).pack()
      
              self.ctr=0
              self.change_it()
      
          def change_it(self):
              """ use random to simulate getting some kind of data 10 times
              """
              this_lit=self.str_var.get()
              next_lit=random.choice(range(100))
              self.str_var.set(this_lit+", "+str(next_lit))
              self.ctr += 1
              if self.ctr < 10:
                  self.master.after(500, self.change_it)
      
      root = tk.Tk()
      UL=UpdateLabel(root)
      root.mainloop()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-17
        • 1970-01-01
        • 1970-01-01
        • 2020-09-28
        • 2021-07-16
        • 1970-01-01
        • 1970-01-01
        • 2020-10-18
        相关资源
        最近更新 更多