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()
答案 0 :(得分:2)
使用进程生成时,子进程无法更新父进程的变量。 您可以通过修改代码进行试验:
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
globalv将在通过线程调用runner时更新,而不是在通过进程调用runner时更新。 您必须使用队列来让孩子与您的应用程序进行交互。
这是因为子进程使用父进程的上下文副本进行实例化 - 而线程使用与父进程相同的上下文。
答案 1 :(得分:1)
你还没有说过为什么这里需要多处理。如果你只想更新一个变量,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()