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

2024-09-29 21:37:26 发布

您现在位置:Python中文网/ 问答频道 /正文

当我第二次执行基于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())

Tags: runinpyselfmaindefthreadfile
2条回答

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

在python中: Trying to create a dialog in another thread wxpython

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

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

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

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

相关问题 更多 >

    热门问题