WxPython: event handling order for multiple handlers of the same event at the same event propagation level

I am a relatively experienced user with wxPython, but have always had problems with how wxPython deals with binding multiple event handlers to the same event (I know that I am a general, I hope my example below is more specific). This is not a "event propagation" issue, as is commonly mentioned in the wxPython community.

Here is an example code (if this did not work out correctly: I could not figure out the code system for the forum):

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

The “OnKeyText2” function is executed first, so I describe the behavior for the “event stack” (is there a suitable terminology for this part of wxPython instead of the “event stack”?) For this control: each new handler associated with the same event on the same distribution level, goes to the top of the stack (executed first), and not to the bottom (executed second).

Despite the fact that I understand this, it has become a real pain in my application, because I have subclasses of the class in which the base class functions bind some events, and then the subclasses bind their additional afterword events.

I feel that the events fall back into the "event stack" (bind the event you want to have in the past). Is there a way for events to be added to the "event stack" and not inserted at the beginning?

If I misunderstand the event.Skip () command or something is missing, let me know! :) Is there a better way to do what I'm trying to do? I do not want the events to be related to each other (for example: has OnKeyText (), as soon as this is done, call OnKeyText2 ()), because in my application one of the event handlers is common for all subclasses and the other is not.

If the answer is that “it just needs to be done in reverse order”, then I have to accept this and make changes to my application.

If the answer is that I should use event distribution between the control and panels to control the order of event handlers, it seems to me that I am facing the same problem if I do not contain the number of event handlers, one for each distribution level .

Thanks in advance! Benjamin

+4
source share
1 answer

I'm not sure I understand why ordering is important in your case, but I had a similar problem.

I initially had one event handler on several TextCtrl that actually worked on a EVT_TEXT_ENTER . Then I wanted to check the input string, as I was expecting a positive integer in the text box. I subclassed TextCtrl for this purpose and hooked up an event handler in a subclass to check the string.

Of course, a problem arose: it worked fine with only half of TextCtrl s, when the event handler checked the subclass before the superclass event handler checked.

I did not investigate how the handlers were handled / processed internally, but instead corrected the design: the subclass event handler is bound to EVT_TEXT_ENTER , which fires the user event that I entered after checking the string. The superclass event handler is now bound to this custom event, rather than EVT_TEXT_ENTER .

Thus, I am always sure of the processing order, and it is insensitive to untying / regaining. I could attach more handlers to the custom event if it is a prerequisite for checking the string for them.

0
source

All Articles