从另一个fram运行wx python的事件循环

2024-10-01 04:45:15 发布

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

我正在用Pyglet编写一个游戏,但是我想加入一些wx对话框。 我可以做一些简单的事情,比如文本输入对话框和消息框(作为模式对话框,在按下ok或cancel之前一直阻止),但是在多人环境中。。。这很难奏效。 我使用的是wxpython,Phoenix 4.0.0b1,我需要从pyglet“驱动”wx的事件循环。我可以安排函数在任何时间间隔运行,但我不确定如何确切地“驱动”事件循环。 有一个EventLoopBase,其中提到了“Dispatch”、“DispatchTimeout”和“Pending”等方法,但我不确定是否wx.App.MainLoop()在跑步前做了什么特别的事wx.EventLoopBase.Run();我不认为我能创造一个wx.应用程序()实例,并进行函数检查,检查是否有挂起的事件,如果有,则运行分派。在

有人知道“正确”的方法吗?如果不需要的话,我宁愿不把循环推到另一个线程上。在

如果我上面概述的方法确实有效的话,这可能不是一个大问题,但万一我把它扔出去,以确保我不会破坏那些看起来有效或根本不起作用的东西。在

更新:下面是我为解决这个问题而写的一些代码。而不是获取wx.应用程序,我得到一个此类并正常调用MainLoop()。 它也不能按它需要的方式工作;wx不认为我使用的事件循环是“主”循环,我相信这就是我运行Show()的对话框出现问题的原因。在

希望这能更好地说明我所要做的,即每隔一段时间调用一个方法来处理wx的循环。 通常,MainLoop()在wx.应用程序执行此操作时会阻塞实例,从而有效地使wx需要驱动其他任何东西的循环,而我正试图让它以另一种方式工作。 在wx的邮件列表here上也有一个线程,它提出了我同样的问题,不过除了“让wx成为主循环并在wx定时器有人建议说。不过,正如我在这里提到的,pyglet的循环将完成大部分工作,因此尝试这样做似乎更有意义。在

代码:

# Overridden classes for wx

import wx

class App(wx.App):

    def MainLoop(self, clock, loop_interval, idle_ticks=50):
        """Indicates that the event loop should start.
This implementation uses pyglet's clock to drive the event loop, and will return immediately after scheduling the driving of the loop.
Args:
    clock: pyglet's clock instance; is used to schedule the main loop.
    loop_interval: in milliseconds, how often the wx loop should be ticked (events processed).
    idle_ticks: how many ticks with no UI events to process should elapse before ProcessIdle is called.
        """
        self.loop_interval = loop_interval
        self.idle_ticks = idle_ticks
            self.ticks = 0
        self.evtloop = wx.GUIEventLoop()
        wx.EventLoop.SetActive(self.evtloop)
        self.run = True
        clock.schedule_interval(self.drive_loop, loop_interval)

    def drive_loop(self, *a):
        """Drives the main wx event loop."""
        if self.run == True:
            while self.evtloop.Pending(): # if there is at least one event to be processed
                self.evtloop.Dispatch() # process one event
            else: # no UI events
                self.ticks += 1
                if self.ticks >= self.idle_ticks:
                    self.evtloop.ProcessIdle()
                    self.ticks = 0

Tags: the方法selfloopevent事件对话框pyglet