wxPython:同一事件传播级别的同一事件的多个处理程序的事件处理顺序

时间:2012-08-30 17:09:44

标签: wxpython

我是wxPython的相对有经验的用户,但是总是遇到wxPython如何处理将多个事件处理程序绑定到同一事件的问题(我知道我是一般的,希望下面我的例子更具体)。这不是关于“事件传播”的问题,因为它通常在wxPython社区中引用。

以下是示例代码(如果它没有正确显示:我无法找到论坛的代码块系统):

import wx

class MainFrame(wx.Frame):
    def __init__(self, parent, ID, title):
       wx.Frame.__init__(self, parent, ID, title,
                      wx.DefaultPosition, wx.Size(200, 100))

       Panel = wx.Panel(self, -1)
       TopSizer = wx.BoxSizer(wx.VERTICAL)
       Panel.SetSizer(TopSizer)

       Text = wx.TextCtrl(Panel, -1, "Type text here")
       TopSizer.Add(Text, 1, wx.EXPAND)

       Text.Bind(wx.EVT_KEY_DOWN,self.OnKeyText)
       Text.Bind(wx.EVT_KEY_DOWN, self.OnKeyText2)


    def OnKeyText(self, event):
        print "OnKeyText"
        event.Skip()

    def OnKeyText2(self, event):
        print "OnKeyText2"
        event.Skip()

class MyApp(wx.App):
    def OnInit(self):
        Frame = MainFrame(None, -1, "Event Order Demo")
        Frame.Show(True)
        self.SetTopWindow(Frame)
        return True

if __name__ == '__main__':
    App = MyApp(0)
    App.MainLoop()

首先执行函数“OnKeyText2”,所以我想出了“事件堆栈”的行为(wxPython的这一部分是否有适当的术语而不是“事件堆栈”?)这个控件是:每个新的处理程序在相同的传播级别绑定到同一事件会进入堆栈顶部(先执行)而不是底部(执行第二个)。

即使我理解这一点,它已成为我的应用程序中的一个真正的痛苦,因为我有一个类的子类,其中基类函数绑定一些事件,然后子类绑定其他事件后。

我觉得这些事件会被反向放入“事件堆栈”中(绑定您希望最后发生的事件)。有没有办法让事件追加到“事件堆栈”而不是在开头插入?

如果我误解了event.Skip()命令或遗失了什么,请告诉我! :)有没有更好的方法来做我想做的事情?我不希望将事件串在一起(例如:有OnKeyText(),一旦完成,调用OnKeyText2())因为在我的应用程序中,其中一个事件处理程序由所有子类共享而另一个不是。

如果答案是“它只需要以相反的顺序完成”,那么我将不得不接受并对我的应用进行更改。

如果答案是我应该在控件和面板之间使用事件传播来控制事件处理程序的顺序,我觉得我遇到了同样的问题,除非我为每个传播级别保持事件处理程序的数量为1

提前致谢! 本杰明

1 个答案:

答案 0 :(得分:0)

我不确定我理解为什么订单在您的情况下很重要,但我遇到了类似的问题。

我最初在几个TextCtrl上有一个事件处理程序,它实际上完成了对EVT_TEXT_ENTER做出反应的工作。然后我想验证输入的字符串,因为我期望文本字段中有一个正整数。为此目的,我将TextCtrl子类化,并在子类中挂钩了一个事件处理程序,用于字符串验证。

当然,有一个问题:当子类事件处理程序的验证在超类事件处理程序的工作之前完成时,它只有一半的TextCtrl工作正常。

我没有研究如何在内部管理/处理处理程序,而是修改了设计:子类事件处理程序绑定到EVT_TEXT_ENTER,在验证字符串后,它会引发我引入的自定义事件。现在,超类事件处理程序已挂接到此自定义事件而不是EVT_TEXT_ENTER

这样,我总是确定处理顺序,并且它对解绑/重新绑定不敏感。如果字符串验证是他们的先决条件,我可以在自定义事件上挂钩更多处理程序。