在Linux上使用多重处理时,TKinter窗口不出现 [英] TKinter windows do not appear when using multiprocessing on Linux

查看:66
本文介绍了在Linux上使用多重处理时,TKinter窗口不出现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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:

  1. 尽管多处理模块紧随线程而动,但这绝对不是精确匹配.一个例子:因为一个参数 流程必须是可刺的,我不得不经历很多代码 进行更改以避免通过Tkinter对象,因为这些对象不是 可刺的.线程模块不会发生这种情况.

  1. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆