在Linux上使用多重处理时,TKinter窗口不出现 [英] TKinter windows do not appear when using multiprocessing on Linux
问题描述
我想在应用程序的其余部分继续运行时,生成另一个进程以异步显示错误消息.
I want to spawn another process to display an error message asynchronously while the rest of the application continues.
我正在使用Python 2.6中的multiprocessing
模块来创建该进程,并且试图显示带有TKinter
的窗口.
I'm using the multiprocessing
module in Python 2.6 to create the process and I'm trying to display the window with TKinter
.
此代码在Windows上可以正常运行,但是如果我调用'showerror("MyApp Error", "Something bad happened.")'
,则不会在Linux上运行TKinter
窗口.如果我通过直接调用showerrorprocess
在同一过程中运行它,它会出现.鉴于此,TKinter
似乎正常工作.我可以打印到控制台并通过multiprocessing
生成的进程执行其他操作,因此它似乎也可以正常工作.
This code worked okay on Windows, but running it on Linux the TKinter
window does not appear if I call 'showerror("MyApp Error", "Something bad happened.")'
. It does appear if I run it in the same process by calling showerrorprocess
directly. Given this, it seems TKinter
is working properly. I can print to the console and do other things from processes spawned by multiprocessing
, so it seems to be working too.
他们似乎并没有一起工作.我是否需要做一些特殊的事情以允许生成的子进程创建窗口?
They just don't seem to work together. Do I need to do something special to allow spawned subprocesses to create windows?
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
是由父进程导入的,并继承"到子进程中,但是以某种方式它的状态与父进程有着千丝万缕的联系,因此它不能在子进程中工作.只要您确保在生成子进程之前不导入TKinter
,它就会起作用,因为那是第一次导入它的是子进程.
The issue seems to be that TKinter
was imported by the parent process, and "inherited" into the child process, but somehow its state is inextricably linked to the parent process and it cannot work in the child. So long as you make sure not to import TKinter
before you spawn the child process, it will work because then it is the child process that is importing it for the first time.
推荐答案
此讨论可能会有所帮助.
这是我发现的一些示例问题:
Here's some sample problems I found:
-
尽管多处理模块紧随线程而动,但这绝对不是精确匹配.一个例子:因为一个参数 流程必须是可刺的,我不得不经历很多代码 进行更改以避免通过
Tkinter
对象,因为这些对象不是 可刺的.线程模块不会发生这种情况.
While the multiprocessing module follows threading closely, it's definitely not an exact match. One example: since parameters to a process must be pickleable, I had to go through a lot of code changes to avoid passing
Tkinter
objects since these aren't pickleable. This doesn't occur with the threading module.
process.terminate()
并没有真正起作用.第二次或第三次尝试只是将解释器挂起,可能是
因为数据结构已损坏(API中已提及,但这是
很少安慰).
process.terminate()
doesn't really work after the first attempt. The second or third attempt simply hangs the interpreter, probably
because data structures are corrupted (mentioned in the API, but this
is little consolation).
这篇关于在Linux上使用多重处理时,TKinter窗口不出现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!