在 Linux 上使用多处理时不出现 TKinter 窗口

Posted

技术标签:

【中文标题】在 Linux 上使用多处理时不出现 TKinter 窗口【英文标题】:TKinter windows do not appear when using multiprocessing on Linux 【发布时间】:2010-09-29 10:56:40 【问题描述】:

我想在应用程序的其余部分继续运行时生成另一个进程以异步显示错误消息。

我正在使用 Python 2.6 中的 multiprocessing 模块来创建进程,并尝试使用 TKinter 显示窗口。

这段代码在 Windows 上运行良好,但在 Linux 上运行它,如果我调用 'showerror("MyApp Error", "Something bad happened.")'TKinter 窗口不会出现。如果我通过直接调用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 是由父进程导入的,并“继承”到子进程中,但不知何故,它的状态与父进程密不可分,无法在子进程中工作。只要您确保在生成子进程之前不导入TKinter,它就会起作用,因为这是第一次导入它的子进程。

【问题讨论】:

它是否获得了所需的环境? 我不介意将其分成更多段落的编辑,但其中一些标点编辑实际上破坏了语法并使其更难阅读。所有这些细微的调整是否有原因? 【参考方案1】:

这个discussion 可能会有所帮助。

这是我发现的一些示例问题:

    虽然多处理模块与线程密切相关,但绝对不是完全匹配。一个例子:因为参数 进程必须是pickleable,我不得不经历很多代码 更改以避免传递 Tkinter 对象,因为这些不是 可腌制。线程模块不会发生这种情况。

    process.terminate() 在第一次尝试后实际上不起作用。第二次或第三次尝试只是挂起解释器,可能 因为数据结构已损坏(在 API 中提到,但这 有点安慰)。

【讨论】:

啊哈!你给了我一个想法。我的主进程不需要 Tkinter,所以我将导入所有 tkinter 内容的行移到 showerrorprocess 中,它起作用了!我猜想多处理一定已经拾取了 Tkinter 模块中的所有状态。我想知道如何阻止它这样做。【参考方案2】:

也许在从同一个 shell 调用你的程序之前调用 shell 命令 xhost + 会起作用吗?

我猜你的问题出在 X 服务器上。

【讨论】:

我试了一下,但没有运气。

以上是关于在 Linux 上使用多处理时不出现 TKinter 窗口的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 Linux 编译的二进制文件在 Windows 上运行时不起作用?

在休眠多租户应用程序中启动时不查找数据源

不使用多处理但在使用 PyTorch DataLoader 时在 google colab 上出现 CUDA 错误

使用yum更新时不升级Linux内核的方法

linux三大文件处理工具(grep/sed/awk)

多处理池的python保存数据在linux上没有给出预期的结果