我是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()
Run Code Online (Sandbox Code Playgroud)
函数"OnKeyText2"首先被执行,所以我想出了"事件堆栈"的行为(wxPython的这部分是否有适当的术语而不是"事件堆栈"?)这个控件是:每个新的处理程序绑定到在相同传播级别的相同事件进入堆栈的顶部(首先执行)而不是底部(执行第二个).
即使我理解这一点,它已成为我的应用程序中的一个真正的痛苦,因为我有一个类的子类,其中基类函数绑定一些事件,然后子类绑定其他事件后.
我觉得这些事件会被反向放入"事件堆栈"(绑定你想要在最后发生的事件).有没有办法让事件附加到"事件堆栈"而不是在开头插入?
如果我误解了event.Skip()命令或遗漏了什么,请告诉我!:)有没有更好的方法来做我想做的事情?我不希望将事件串在一起(例如:有OnKeyText(),一旦完成,调用OnKeyText2())因为在我的应用程序中,其中一个事件处理程序由所有子类共享而另一个不是.
如果答案是"它只需要以相反的顺序完成",那么我将不得不接受并对我的应用程序进行更改.
如果答案是我应该在控件和面板之间使用事件传播来控制事件处理程序的顺序,我觉得我遇到了同样的问题,除非我将每个传播级别的事件处理程序的数量保持为1.
提前致谢!本杰明
小智 0
我不确定我是否理解为什么顺序对您的情况很重要,但我也遇到了类似的问题。
我最初在多个事件处理程序上有一个事件处理程序TextCtrl,它实际上完成了对EVT_TEXT_ENTER. 然后我想验证输入的字符串,因为我期望文本字段中输入正整数。TextCtrl为此,我进行了子类化,并在子类中挂钩了一个事件处理程序以进行字符串验证。
当然,有一个问题:TextCtrl当子类事件处理程序的验证在超类事件处理程序的工作之前完成时,它只对一半的 s 运行良好。
我没有研究处理程序是如何在内部管理/处理的,而是修复了设计:子类事件处理程序绑定到EVT_TEXT_ENTER,在验证字符串后触发我引入的自定义事件。超类事件处理程序现在挂接到该自定义事件而不是EVT_TEXT_ENTER.
这样,我总是可以确定处理顺序,并且对解除绑定/重新绑定不敏感。如果字符串验证是它们的先决条件,我可以在自定义事件上挂钩更多处理程序。