wxPython wx.CallAfter - 如何让它立即执行?

时间:2014-07-07 16:07:09

标签: python events wxpython

当我用wx.CallAfter执行一个函数时,在其中设置一个变量。我希望能够在下一行获取该变量的值,但是CallAfter似乎稍后会执行该函数。我认为它将它推送到稍后处理的某个队列中或某些东西......有没有办法让该队列立即被处理?

这是wx.CallAfter的代码:

def CallAfter(callableObj, *args, **kw):
    """
    Call the specified function after the current and pending event
    handlers have been completed.  This is also good for making GUI
    method calls from non-GUI threads.  Any extra positional or
    keyword args are passed on to the callable when it is called.

    :see: `wx.CallLater`
    """
    assert callable(callableObj), "callableObj is not callable"
    app = wx.GetApp()
    assert app is not None, 'No wx.App created yet'

    if not hasattr(app, "_CallAfterId"):
        app._CallAfterId = wx.NewEventType()
        app.Connect(-1, -1, app._CallAfterId,
                    lambda event: event.callable(*event.args, **event.kw) )
    evt = wx.PyEvent()
    evt.SetEventType(app._CallAfterId)
    evt.callable = callableObj
    evt.args = args
    evt.kw = kw
    wx.PostEvent(app, evt)

我的假设是,wx.PostEvent放置' evt'在某个内部容器中的应用程序'并且在某些时候,容器被迭代并且所有元素都具有可调用的'执行还是什么?所以基本上我需要立即引起这种情况,但我找不到任何看起来像'wx.ForceEventProcessing()'或者' wx.FlushEventsQueue'

我尝试在定义方法的面板中调用self.Update(),但是这只是阻止了应用程序并且它停止响应。

2 个答案:

答案 0 :(得分:4)

正如您所猜测的那样wx.CallAfter将呼叫信息添加到队列(待处理事件队列,在下次清空事件队列时在GUI线程中处理)然后立即返回。换句话说,它旨在成为“即发即忘”的函数调用。

如果您需要获取该被调用函数的结果,可以采取一些方法。一个是延迟结果模式,基本上你得到一个结果对象,它将在调用之后接收函数调用的结果,并且调用代码可以在发生时获得通知。在wx.lib.delayedresult中有一个这样的实现,可能在不同的地方可以找到这种模式的其他实现。关于这种方法的好处是调用线程不必停止并等待结果,并且如果需要可以继续处理其他事情。

我认为另一种非常好的方法是wxAnyThread,可以在https://pypi.python.org/pypi/wxAnyThread/找到。这个模块提供了一个装饰器,它允许从任何线程调用方法,就像普通的函数调用一样,但是当从GUI线程以外的东西调用时,它将使用wx.CallAfter - 就像在UI线程中调用函数一样处理,然后等待结果,并在收到结果时将其返回给调用者。因此,虽然在处理UI事件并调用函数时阻塞了调用线程,但使用起来要简单得多,并降低了调用端的复杂性。

答案 1 :(得分:0)

你试过谷歌吗?我做了,我有几个想法。请参阅以下主题:

尝试 wx.WakeUpIdle() wx.GetApp()。ProcessIdle()。我还在docs中注意到wx.App有一个 ProcessPendingEvents 方法,所以你也可以尝试 wx.Getapp()。ProcessPendingEvents()