2016-10-25 10 views
0

最近私はプロセスで遊び始めました。いくつかのものを試してみるために、私は非常にシンプルなGUIを書き、以下について考えた:パイプを使ってTkinterとStringVarを送る

  • ありラベルであり、ボタンがクリックされた場合、ボタン
  • は、プロセスがチェックする、それに応じてラベルを編集します。これを行うには

、私はそれを送り返し、その後、それを編集し、パイプを通して他のプロセスに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

tkinterオブジェクトを他のプロセスに渡すことはできません。 StringVarの場合は、変数自体(例:txt2go)ではなく、パイプ内の変数の値(例:txt2go.get())のみを送信できます。

+0

ラベルの内容を更新するには何かできますか?任意の回避策? –

+0

@ChatinKöktürk:回避策は、文字列の値を前後に渡すことです。 –

+0

ええ、これを前後に通過させると、この目的にどのように役立つのでしょうか?あなたは少なくとも疑似コードを投稿できますか? –

0

私の問題は、GUIを起動して自分自身を更新できないという問題でした。しかし、いくつかの研究の後で、方法root.update()を発見しました。ここで、rootTk()オブジェクトです。変更をトリガーするには、mainloop()ではなく、while 1:ループでコンテンツを更新する必要があります。

また、Pythonはパイプの代わりにキューを多く使用しているようです。非同期のプロセス間通信はパイプでは困難です。何かが読み取られるまでプロセスは.recv()呼び出しによってブロックされているためです。キューを使用すると、この問題はQueueオブジェクトオプションblock=Falseで解決できます。

関連する問題