我最近开始玩流程。为了尝试一些东西,我写了一个非常简单的GUI并考虑了以下内容:
为此,我尝试通过管道将StringVar发送到另一个进程,编辑它,然后将其发回。相关代码如下:
def changeText(pipe1, pipe2, str):
while 1:
if pipe1[1].recv() == "a":
print("received")
str.set("clicked")
pipe2[0].send(str)
else:
pass
def buttonClicked(pipe):
pipe[0].send("a")
txt2go = tk.StringVar(master=root, value="not clicked")
btn1 = tk.Button(text = "go", command = lambda : buttonClicked(pipe1))
btn1.place(x=50, y=80)
proses1 = mp.Process(target=changeText, args=(pipe1, pipe2, txt2go))
proses1.start()
但是程序提供了以下输出(甚至在我尝试接收StringVar之前):
Process Process-1:
received
Traceback (most recent call last):
File "/usr/lib/python3.5/multiprocessing/process.py", line 249, in _bootstrap
self.run()
File "/usr/lib/python3.5/multiprocessing/process.py", line 93, in run
self._target(*self._args, **self._kwargs)
File "/home/cetin/PycharmProjects/Process_deneme_PC /Process_deneme_pc.py", line 9, in changeText
pipe2[0].send(str)
File "/usr/lib/python3.5/multiprocessing/connection.py", line 206, in send
self._send_bytes(ForkingPickler.dumps(obj))
File "/usr/lib/python3.5/multiprocessing/reduction.py", line 50, in dumps
cls(buf, protocol).dump(obj)
_pickle.PicklingError: Can't pickle <class '_tkinter.tkapp'>: attribute lookup tkapp on _tkinter failed
这是什么意思,你能建议任何解决方法吗?
答案 0 :(得分:0)
您无法将tkinter对象传递给其他进程。在StringVar
的情况下,您只能在管道中发送变量的值(例如:txt2go.get()
),而不是变量本身(例如:txt2go
)。
答案 1 :(得分:0)
我的问题是我无法触发GUI进行自我更新。但是,经过一些研究,我发现了方法root.update()
,其中root
是Tk()
个对象。要触发更改,您必须使用while 1:
循环更新内容,而不是使用mainloop()
。
此外,似乎Python正在更多地使用队列而不是管道。管道的异步进程间通信很困难,因为.recv()
调用阻止了进程,直到有东西要读。使用队列,可以使用Queue
对象选项block=False
克服此问题。