猿问

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())


杨魅力
浏览 280回答 2
2回答

元芳怎么了

问题是您正在与第一次运行相同的 Python 进程中运行第二次传递。这意味着您wx.App在一个进程中创建了多个,这有时可以工作,但通常会遇到某种问题。此外,您正在为第二个线程创建一个新线程,wx.App从 wxWidget 的角度来看,只有创建第一个线程的第一个线程wx.App是“GUI 线程”。因此,如果您遵循wx.App每个进程一个,每个进程一个 GUI 线程[*] 规则,那么您会发现事情会好得多。[*] 请注意,在 OSX 上存在要求 GUI 线程作为主线程的平台限制。

富国沪深

在 wx 框架中,不能为 GUI使用多个线程。有关如何使用wx.CallAfter异步将 GUI 更新从工作线程调度到主线程的更多信息,请参阅这两个链接:在 python 中: 试图在另一个线程 wxpython 中创建一个对话框在 C++ 中: https ://forums.wxwidgets.org/viewtopic.php?t=40332
随时随地看视频慕课网APP

相关分类

Python
我要回答