X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/fd3f2efe791cf99c2e4944cd615f02a5502ed93e..3d2d9036037d9ee51f47d878c3dcef4af4a6ef41:/wxPython/wx/lib/evtmgr.py diff --git a/wxPython/wx/lib/evtmgr.py b/wxPython/wx/lib/evtmgr.py index 236c37f5fc..5c32cacb89 100644 --- a/wxPython/wx/lib/evtmgr.py +++ b/wxPython/wx/lib/evtmgr.py @@ -11,30 +11,34 @@ # Copyright: (c) 2003 by db-X Corporation # Licence: wxWindows license #--------------------------------------------------------------------------- +# 12/02/2003 - Jeff Grimmett (grimmtooth@softhome.net) +# +# o Updated for 2.5 compatability. +# """ -A module that allows multiple handlers to respond to single wxWindows +A module that allows multiple handlers to respond to single wxWidgets events. This allows true NxN Observer/Observable connections: One event can be received by multiple handlers, and one handler can receive multiple events. There are two ways to register event handlers. The first way is -similar to standard wxPython handler registration: +similar to standard wxPython handler registration:: - from wxPython.lib.evtmgr import eventManager + from wx.lib.evtmgr import eventManager eventManager.Register(handleEvents, EVT_BUTTON, win=frame, id=101) There's also a new object-oriented way to register for events. This invocation is equivalent to the one above, but does not require the -programmer to declare or track control ids or parent containers: +programmer to declare or track control ids or parent containers:: eventManager.Register(handleEvents, EVT_BUTTON, myButton) This module is Python 2.1+ compatible. """ -from wxPython import wx -import pubsub +import wx +import pubsub # publish / subscribe library #--------------------------------------------------------------------------- @@ -59,17 +63,20 @@ class EventManager: """ Registers a listener function (or any callable object) to receive events of type event coming from the source window. - For example: - + For example:: + eventManager.Register(self.OnButton, EVT_BUTTON, theButton) Alternatively, the specific window where the event is delivered, and/or the ID of the event source can be specified. - For example: - + For example:: + eventManager.Register(self.OnButton, EVT_BUTTON, win=self, id=ID_BUTTON) - or + + or:: + eventManager.Register(self.OnButton, EVT_BUTTON, theButton, self) + """ # 1. Check if the 'event' is actually one of the multi- @@ -84,9 +91,11 @@ class EventManager: # the natural way of doing things.) if source is not None: id = source.GetId() + if win is None: # Some widgets do not function as their own windows. win = self._determineWindow(source) + topic = (event, win, id) # Create an adapter from the PS system back to wxEvents, and @@ -143,9 +152,11 @@ class EventManager: """ win = self._determineWindow(win) topics = self.__getTopics(win) + if topics: for aTopic in topics: self.__deregisterTopic(aTopic) + del self.windowTopicLookup[win] @@ -160,13 +171,16 @@ class EventManager: for topic in topicList: topicDict = self.messageAdapterDict[topic] + if topicDict.has_key(listener): topicDict[listener].Destroy() del topicDict[listener] + if len(topicDict) == 0: self.eventAdapterDict[topic].Destroy() del self.eventAdapterDict[topic] del self.messageAdapterDict[topic] + del self.listenerTopicLookup[listener] @@ -211,8 +225,8 @@ class EventManager: name = aWin.GetClassName() i = id(aWin) return '%s #%d' % (name, i) - except wx.wxPyDeadObjectError: - return '(dead wxObject)' + except wx.PyDeadObjectError: + return '(dead wx.Object)' def __topicString(self, aTopic): @@ -239,8 +253,10 @@ class EventManager: # This topic isn't valid. Probably because it was deleted # by listener. return + for messageAdapter in messageAdapterList: messageAdapter.Destroy() + self.eventAdapterDict[aTopic].Destroy() del self.messageAdapterDict[aTopic] del self.eventAdapterDict[aTopic] @@ -249,6 +265,7 @@ class EventManager: def __getTopics(self, win=None): if win is None: return self.messageAdapterDict.keys() + if win is not None: try: return self.windowTopicLookup[win] @@ -284,7 +301,7 @@ class EventManager: discovered, the implementation can be changed to a dictionary lookup along the lines of class : function-to-get-window. """ - if isinstance(aComponent, wx.wxMenuItem): + if isinstance(aComponent, wx.MenuItem): return aComponent.GetMenu() else: return aComponent @@ -429,7 +446,7 @@ class EventAdapter: try: if not self.disconnect(): print 'disconnect failed' - except wx.wxPyDeadObjectError: + except wx.PyDeadObjectError: print 'disconnect failed: dead object' ##???? @@ -481,12 +498,11 @@ eventManager = EventManager() if __name__ == '__main__': - from wxPython.wx import wxPySimpleApp, wxFrame, wxToggleButton, wxBoxSizer, wxHORIZONTAL, EVT_MOTION, EVT_LEFT_DOWN, EVT_TOGGLEBUTTON, wxALL - app = wxPySimpleApp() - frame = wxFrame(None, -1, 'Event Test', size=(300,300)) - button = wxToggleButton(frame, -1, 'Listen for Mouse Events') - sizer = wxBoxSizer(wxHORIZONTAL) - sizer.Add(button, 0, 0 | wxALL, 10) + app = wx.PySimpleApp() + frame = wx.Frame(None, -1, 'Event Test', size=(300,300)) + button = wx.ToggleButton(frame, -1, 'Listen for Mouse Events') + sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer.Add(button, 0, 0 | wx.ALL, 10) frame.SetAutoLayout(1) frame.SetSizer(sizer) @@ -502,16 +518,16 @@ if __name__ == '__main__': # Turn the output of mouse events on and off if event.IsChecked(): print '\nEnabling mouse events...' - eventManager.Register(printEvent, EVT_MOTION, frame) - eventManager.Register(printEvent, EVT_LEFT_DOWN, frame) + eventManager.Register(printEvent, wx.EVT_MOTION, frame) + eventManager.Register(printEvent, wx.EVT_LEFT_DOWN, frame) else: print '\nDisabling mouse events...' eventManager.DeregisterWindow(frame) # Send togglebutton events to both the on/off code as well # as the function that prints to stdout. - eventManager.Register(printEvent, EVT_TOGGLEBUTTON, button) - eventManager.Register(enableFrameEvents, EVT_TOGGLEBUTTON, button) + eventManager.Register(printEvent, wx.EVT_TOGGLEBUTTON, button) + eventManager.Register(enableFrameEvents, wx.EVT_TOGGLEBUTTON, button) frame.CenterOnScreen() frame.Show(1)