除0以外的wxPython主线程在退出

时间:2018-03-15 16:18:27

标签: python multithreading wxpython exit wxpython-phoenix

我想在控制台会话中同时使用交互式wxPython GUI(如交互模式下的matplotlib)。这要求控制台继续在线程0上运行,并且所有wx交互都要在单独的线程上运行。 (我很清楚只有一个线程应该访问wx。)

我的演示代码可以正常工作(通过python -i启动时),但在退出Python时会弹出一个wxWidgets Debug Alert(看起来像一个崩溃对话框)(例如通过exit())。 当wx主线程不是线程0时,如何在退出Python时避免警报?

import threading

class GUI(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.daemon = True

    def run(self):
        import wx 
        app = wx.App() 
        window = wx.Frame(None, title="Hello World!", size=(200, 100)) 
        panel = wx.Panel(window) 
        text = wx.StaticText(panel, label="Hello World!", pos=(0, 0)) 
        window.Show(True) 
        app.MainLoop()     

gui_thread = GUI()
gui_thread.start()

Others使用旧版本的wxPython使用这样的策略报告成功,但是他们的代码(案例3)在关闭时给出了与上面相同的崩溃。

我退出时出错(可能来自自动注册的atexit处理程序?),如果您尝试从第二个线程assert "wxIsMathThread()" failed in wxSocketBase::IsInitialized(): unsafe to call from other threads [in thread 1b68]访问wx,则会得到同样的错误。

具体来说,在使用Anaconda Python 3.6.3在Windows 10上运行wxPython 4.0.1(aka Phoenix)时,我得到了wxWidgets Debug Alert。我还没有测试过其他平台和版本。

1 个答案:

答案 0 :(得分:1)

警报来自导入atexit自动插入的wx处理程序。为了避免这种情况,同时仍然允许例行调试,可以在加载atexit后禁用警报wx

import threading
import atexit

class GUI(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.daemon = True

    def run(self):
        import wx 
        atexit.register(disable_asserts)
        app = wx.App() 
        window = wx.Frame(None, title="Hello World!", size=(200, 100)) 
        panel = wx.Panel(window) 
        text = wx.StaticText(panel, label="Hello World!", pos=(0, 0)) 
        window.Show(True) 
        app.MainLoop()

def disable_asserts():
    import wx
    wx.DisableAsserts()

gui_thread = GUI()
gui_thread.start()