Linuxでマルチプロセッシングを使用している場合、TKinterウィンドウが表示されません
-
03-07-2019 - |
質問
別のプロセスを生成して、アプリケーションの残りが継続している間にエラーメッセージを非同期に表示したい。
Python 2.6の multiprocessing
モジュールを使用してプロセスを作成し、 TKinter
でウィンドウを表示しようとしています。
このコードはWindowsでは問題なく機能しましたが、Linuxで TKinter
ウィンドウを実行すると、 'showerror(" MyApp Error&quot ;," Something bad happened。" ;) '
。 showerrorprocess
を直接呼び出して同じプロセスで実行すると 表示されます。これを考えると、 TKinter
は正常に動作しているようです。コンソールに出力したり、 multiprocessing
によって生成されたプロセスから他のことを実行したりできるので、動作しているようです。
これらは一緒に機能していないようです。生成されたサブプロセスがウィンドウを作成できるようにするために、特別なことをする必要がありますか?
from multiprocessing import Process
from Tkinter import Tk, Text, END, BOTH, DISABLED
import sys
import traceback
def showerrorprocess(title,text):
"""Pop up a window with the given title and text. The
text will be selectable (so you can copy it to the
clipboard) but not editable. Returns when the
window is closed."""
root = Tk()
root.title(title)
text_box = Text(root,width=80,height=15)
text_box.pack(fill=BOTH)
text_box.insert(END,text)
text_box.config(state=DISABLED)
def quit():
root.destroy()
root.quit()
root.protocol("WM_DELETE_WINDOW", quit)
root.mainloop()
def showerror(title,text):
"""Pop up a window with the given title and text. The
text will be selectable (so you can copy it to the
clipboard) but not editable. Runs asynchronously in
a new child process."""
process = Process(target=showerrorprocess,args=(title,text))
process.start()
編集
問題は、 TKinter
が親プロセスによってインポートされ、" inherited&quot ;;しかし、どういうわけかその状態は親プロセスに密接にリンクされており、子プロセスでは機能しません。子プロセスを生成する前に TKinter
をインポートしないことを確認する限り、子プロセスが初めてインポートするのは子プロセスであるため動作します。
解決
このディスカッションが役立つ場合があります。
ここに、私が見つけた問題の例をいくつか示します。
マルチプロセッシングモジュールはスレッド化に密接に従いますが、完全に一致するわけではありません。一例:パラメータが プロセスは pickleable でなければならず、多くのコードを実行しなければなりませんでした
Tkinter
オブジェクトは渡さないようにするための変更 pickleable 。これは、スレッドモジュールでは発生しません。
process.terminate()
は、最初の試行後に実際には機能しません。 2回目または3回目の試行では、おそらくインタープリターがハングします。 データ構造が破損しているため(APIに記載されていますが、 少し慰めです)。
他のヒント
同じシェルからプログラムを呼び出す前にシェルコマンド xhost +
を呼び出しても動作しますか?
あなたの問題はXサーバーにあると推測しています。