为了账号安全,请及时绑定邮箱和手机立即绑定

wxPython:只有主线程可以处理 Windows 消息错误

wxPython:只有主线程可以处理 Windows 消息错误

杨魅力 2022-07-12 10:16:06
当我第二次执行基于 wxpython 的 UI 时,我在下面发现了这个错误。UI 第一次启动和关闭时,它没有错误。但是,如果再次启动并关闭,则会出现一些错误,如下所示。我添加了一些调试日志以查看下面的线程名称。有谁知道这里有什么问题?一般来说,我想为主窗体创建新线程。>>> import testui>>> testui.run()Launching TestUI thread...    thread1 = MainThreadthread3 = Thread-11  thread4 = Thread-11thread2 = MainThread>>> testui.run()Launching TestUI thread...thread1 = MainThreadthread3 = Thread-12Exception in thread Thread-12:Traceback (most recent call last):File "c:\python27\lib\threading.py", line 801, in __bootstrap_innerself.run()File "c:\python27\lib\threading.py", line 754, in runself.__target(*self.__args, **self.__kwargs)File "c:\test\testui.py", line 587, in ui_thread_functionapps.MainLoop()File "c:\python27\lib\site-packages\wx\core.py", line 2096, in MainLooprv = 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 messagesthread2 = 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 = Noneclass TestUIApp(wx.App):    def OnInit(self):        global frmMainForm        frmMainForm = MainFrame(None, wx.ID_ANY, "")        self.SetTopWindow(frmMainForm)        frmMainForm.Show()        frmMainForm.Center()        return Truedef 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())
查看完整描述

2 回答

?
元芳怎么了

TA贡献1798条经验 获得超7个赞

问题是您正在与第一次运行相同的 Python 进程中运行第二次传递。这意味着您wx.App在一个进程中创建了多个,这有时可以工作,但通常会遇到某种问题。此外,您正在为第二个线程创建一个新线程,wx.App从 wxWidget 的角度来看,只有创建第一个线程的第一个线程wx.App是“GUI 线程”。

因此,如果您遵循wx.App每个进程一个,每个进程一个 GUI 线程[*] 规则,那么您会发现事情会好得多。

[*] 请注意,在 OSX 上存在要求 GUI 线程作为主线程的平台限制。


查看完整回答
反对 回复 2022-07-12
?
富国沪深

TA贡献1790条经验 获得超9个赞

在 wx 框架中,不能为 GUI使用多个线程。有关如何使用wx.CallAfter异步将 GUI 更新从工作线程调度到主线程的更多信息,请参阅这两个链接:

在 python 中: 试图在另一个线程 wxpython 中创建一个对话框

在 C++ 中: https ://forums.wxwidgets.org/viewtopic.php?t=40332


查看完整回答
反对 回复 2022-07-12
  • 2 回答
  • 0 关注
  • 279 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号