繁体   English   中英

Python多处理和tkinter - 如何连接这个过程(GUI和衍生过程)?

[英]Python multiprocessing and tkinter - how to connect this process (GUI and spawned process)?

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

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()

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

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时,不会更新。 您必须使用队列来让孩子与您的应用程序进行交互。

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

你还没有说过为什么这里需要多处理。 如果你只是想更新一个变量,那么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()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM