python - wxPython:只有主线程可以处理 Windows 消息错误
问题描述
当我第二次执行基于 wxpython 的 UI 时,我在下面发现了这个错误。UI 第一次启动和关闭时,它没有错误。但是,如果再次启动并关闭,则会出现一些错误,如下所示。我添加了一些调试日志以查看下面的线程名称。有谁知道这里有什么问题?一般来说,我想为主窗体创建新线程。
>>> import testui
>>> testui.run()
Launching TestUI thread...
thread1 = MainThread
thread3 = Thread-11
thread4 = Thread-11
thread2 = MainThread
>>> testui.run()
Launching TestUI thread...
thread1 = MainThread
thread3 = Thread-12
Exception in thread Thread-12:
Traceback (most recent call last):
File "c:\python27\lib\threading.py", line 801, in __bootstrap_inner
self.run()
File "c:\python27\lib\threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "c:\test\testui.py", line 587, in ui_thread_function
apps.MainLoop()
File "c:\python27\lib\site-packages\wx\core.py", line 2096, in MainLoop
rv = wx.PyApp.MainLoop(self)
wxAssertionError: C++ assertion "wxThread::IsMain()" failed at ..\..\src\msw\evtloop.cpp(182) in
wxGUIEventLoop::Dispatch(): only the main thread can process Windows messages
thread2 = MainThread
这是代码片段:
import threading
class MainFrame(wx.Frame):
def __init__(self, *args, **kwds):
self.Bind(wx.EVT_CLOSE, self.OnClose)
...
def OnClose(self, event):
self.Destroy()
frmMainForm = None
class TestUIApp(wx.App):
def OnInit(self):
global frmMainForm
frmMainForm = MainFrame(None, wx.ID_ANY, "")
self.SetTopWindow(frmMainForm)
frmMainForm.Show()
frmMainForm.Center()
return True
def ui_thread_function():
print("Launching Test UI thread...\n")
apps = TestUIApp(0)
main_thread = threading.currentThread()
print("thread3 = %s" % main_thread.getName())
apps.MainLoop()
main_thread = threading.currentThread()
print("thread4 = %s" % main_thread.getName())
def run():
x = threading.Thread(target=ui_thread_function)
x.start()
main_thread = threading.currentThread()
print("thread1 = %s\n" % main_thread.getName())
x.join()
main_thread = threading.currentThread()
print("thread2 = %s" % main_thread.getName())
解决方案
在 wx 框架中,不能为 GUI使用多个线程。有关如何使用wx.CallAfter
异步将 GUI 更新从工作线程调度到主线程的更多信息,请参阅这两个链接:
在 python 中: 试图在另一个线程 wxpython 中创建一个对话框
在 C++ 中: https ://forums.wxwidgets.org/viewtopic.php?t=40332
推荐阅读
- flutter - 颤振:库比蒂诺标签栏
- flutter - Flutter:如何在 Firestore 中更新数组中的数组
- drake - 指南针步态的直接转录
- flutter - Flutter CustomTimerPainter 我们如何在后台运行它,这样计时器就不会在处理时停止
- ruby-on-rails - development.rb:45:in `block in
': nil:NilClass (NoMethodError) 的未定义方法 `[]' - c - 如何使最小的 setup.exe 适合病毒总数?
- typescript - 打字稿类型:根据其他参数检查正确的回调类型
- python - pandas:没有明显的方法在 python 3.8 中将列设置为应用函数的输出
- twilio - 运行 npm run deploy:twilio-cli 会导致以下错误
- reactjs - 基于 API 返回的 React 切换按钮