Tkinter并通过管道发送StringVar

时间:2016-10-25 10:40:32

标签: python tkinter pipe

我最近开始玩流程。为了尝试一些东西,我写了一个非常简单的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

这是什么意思,你能建议任何解决方法吗?

2 个答案:

答案 0 :(得分:0)

您无法将tkinter对象传递给其他进程。在StringVar的情况下,您只能在管道中发送变量的值(例如:txt2go.get()),而不是变量本身(例如:txt2go)。

答案 1 :(得分:0)

我的问题是我无法触发GUI进行自我更新。但是,经过一些研究,我发现了方法root.update(),其中rootTk()个对象。要触发更改,您必须使用while 1:循环更新内容,而不是使用mainloop()

此外,似乎Python正在更多地使用队列而不是管道。管道的异步进程间通信很困难,因为.recv()调用阻止了进程,直到有东西要读。使用队列,可以使用Queue对象选项block=False克服此问题。