我想在控制台会话中同时使用交互式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。我还没有测试过其他平台和版本。
答案 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()