1.. include:: headings.inc
2
3
4.. _events and event handling:
5
6==============================================
7|phoenix_title|  **Events and Event Handling**
8==============================================
9
10
11Like with all the other GUI frameworks, the control of flow in
12wxPython applications is event-based: the program normally performs
13most of its actions in response to the events generated by the
14user. These events can be triggered by using the input devices (such
15as keyboard, mouse, joystick) directly or, more commonly, by a
16standard control which synthesizes such input events into higher level
17events: for example, a :ref:`wx.Button` can generate a click event when
18the user presses the left mouse button on it and then releases it
19without pressing ``Esc`` in the meanwhile. There are also events which
20don't directly correspond to the user actions, such as
21:ref:`wx.TimerEvent`.
22
23But in all cases wxPython represents these events in a uniform way and
24allows you to handle them in the same way wherever they originate
25from. And while the events are normally generated by wxPython itself,
26you can also do this, which is especially useful when using custom
27events (see :ref:`Custom Event Summary <custom event summary>`).
28
29To be more precise, each event is described by:
30
31- **Event type**: this is simply a value of type `EventType` which
32  uniquely identifies the type of the event.  For example, clicking on
33  a button, selecting an item from a list box and pressing a key on
34  the keyboard all generate events with different event types.
35
36- **Event class**: carried by the event: each event has some information
37  associated with it and this data is represented by an object of a
38  class derived from :ref:`wx.Event`. Events of different types can
39  use the same event class, for example both button click and listbox
40  selection events use :ref:`wx.CommandEvent` class (as do all the
41  other simple control events), but the key press event uses
42  :ref:`wx.KeyEvent` as the information associated with it is
43  different.
44
45- **Event source**: :ref:`wx.Event` stores the object which generated the
46  event and, for windows, its identifier (see :ref:`Window Identifiers
47  <window identifiers>`). As it is common to have more than one object
48  generating events of the same type (e.g. a typical window contains
49  several buttons, all generating the same button click event),
50  checking the event source object or its id allows to distinguish
51  between them.
52
53
54
55.. _event handling:
56
57Event Handling
58--------------
59
60There is one principal way to handle events in wxPython, which uses
61the :meth:`wx.EvtHandler.Bind` call and can be used to bind and unbind
62the handlers dynamically, i.e. during run-time depending on some
63conditions. It also allows the direct binding of events to:
64
65- A handler method in the same or another object.
66- An ordinary function like a static method or a global function.
67- An arbitrary callable object.
68
69
70
71.. _dynamic event handling:
72
73Dynamic Event Handling
74----------------------
75
76Let us start by looking at the syntax: in any place in your code, but
77usually in the code of the class defining the handler itself, call its
78``Bind()`` method like this::
79
80	class MyFrame(wx.Frame):
81	    def __init__(self, parent):
82	        wx.Frame.__init__(self, parent)
83
84                # Other initialization code...
85
86                self.Bind(wx.EVT_MENU, self.OnExit, id=wx.ID_EXIT)
87
88
89
90Event handlers can be bound at any moment. For example, it's possible
91to do some initialization first and only bind the handlers if and when
92it succeeds. This can avoid the need to test that the object was
93properly initialized in the event handlers themselves. With ``Bind()``
94they simply won't be called if it wasn't correctly initialized.
95
96As a slight extension of the above, the handlers can also be unbound
97at any time with :meth:`wx.EvtHandler.Unbind` (and maybe rebound
98later).
99
100Almost last but very, very far from least is the flexibility which
101allows to bind an event to:
102
103- A method in another object.
104- An ordinary function like a static method or a global function.
105- An arbitrary function.
106
107
108Let us now look at more examples of how to use different event
109handlers using the two overloads of ``Bind()`` function: first one for
110the object methods and the other one for arbitrary functors (callable
111objects, including simple functions).
112
113In addition to using a method of the object generating the event
114itself, you can use a method from a completely different object as an
115event handler::
116
117	def OnFrameExit(event):
118	    # Do something useful.
119	    pass
120
121	class MyFrame(wx.Frame):
122	    def __init__(self, parent):
123	        wx.Frame.__init__(self, parent)
124
125                # Other initialization code...
126
127                self.Bind(wx.EVT_MENU, OnFrameExit, id=wx.ID_EXIT)
128
129
130
131Note that `MyFrameHandler` doesn't need to derive from
132:ref:`wx.EvtHandler`.
133
134
135
136.. _how events are processed:
137
138How Events are Processed
139------------------------
140
141The previous sections explain how to define event handlers but don't
142address the question of how exactly wxPython finds the handler to call
143for the given event. This section describes the algorithm used in
144detail.
145
146When an event is received from the windowing system, wxPython calls
147:meth:`wx.EvtHandler.ProcessEvent` on the first event handler object
148belonging to the window generating the event. The normal order of
149event table searching by ``ProcessEvent`` is as follows, with the
150event processing stopping as soon as a handler is found (unless the
151handler calls :meth:`wx.Event.Skip` in which case it doesn't count as
152having handled the event and the search continues):
153
1541. Before anything else happens, :meth:`wx.AppConsole.FilterEvent` is
155   called. If it returns anything but -1 (default), the event handling
156   stops immediately.
157
1582. If this event handler is disabled via a call to
159   :meth:`wx.EvtHandler.SetEvtHandlerEnabled` the next three steps are
160   skipped and the event handler resumes at step (5).
161
1623. If the object is a :ref:`wx.Window` and has an associated validator,
163   :ref:`wx.Validator` gets a chance to process the event.
164
1654. The list of dynamically bound event handlers, i.e., those for which
166   ``Bind()`` was called, is consulted.
167
1685. The event table containing all the handlers defined using the event
169   table macros in this class and its base classes is examined. Notice
170   that this means that any event handler defined in a base class will
171   be executed at this step.
172
1736. The event is passed to the next event handler, if any, in the event
174   handler chain, i.e., the steps (1) to (4) are done for it. Usually
175   there is no next event handler so the control passes to the next
176   step but see :ref:`Event Handlers Chain <event handlers chain>` for
177   how the next handler may be defined.
178
1797. If the object is a :ref:`wx.Window` and the event is set to
180   propagate (by default only event types derived from
181   :ref:`wx.CommandEvent` are set to propagate), then the processing
182   restarts from the step (1) (and excluding the step (7)) for the
183   parent window. If this object is not a window but the next handler
184   exists, the event is passed to its parent if it is a window. This
185   ensures that in a common case of (possibly several) non-window
186   event handlers pushed on top of a window, the event eventually
187   reaches the window parent.
188
1898. Finally, i.e., if the event is still not processed, the
190   :ref:`wx.App` object itself (which derives from
191   :ref:`wx.EvtHandler`) gets a last chance to process it.
192
193
194**Please pay close attention to step 6!** People often overlook or get
195confused by this powerful feature of the wxPython event processing
196system. The details of event propagation up the window hierarchy are
197described in the next section.
198
199
200
201.. _how events propagate upwards:
202
203How Events Propagate Upwards
204^^^^^^^^^^^^^^^^^^^^^^^^^^^^
205
206As mentioned above, the events of the classes deriving from
207:ref:`wx.CommandEvent` are propagated by default to the parent window if
208they are not processed in this window itself. But although by default
209only the command events are propagated like this, other events can be
210propagated as well because the event handling code uses
211:meth:`wx.Event.ShouldPropagate` to check whether an event should be
212propagated. It is also possible to propagate the event only a limited
213number of times and not until it is processed (or a top level parent
214window is reached).
215
216Finally, there is another additional complication (which, in fact,
217simplifies life of wxPython programmers significantly): when
218propagating the command events up to the parent window, the event
219propagation stops when it reaches the parent dialog, if any. This
220means that you don't risk getting unexpected events from the dialog
221controls (which might be left unprocessed by the dialog itself because
222it doesn't care about them) when a modal dialog is popped up. The
223events do propagate beyond the frames, however. The rationale for this
224choice is that there are only a few frames in a typical application
225and their parent-child relation are well understood by the programmer
226while it may be difficult, if not impossible, to track down all the
227dialogs that may be popped up in a complex program (remember that some
228are created automatically by wxPython).  If you need to specify a
229different behaviour for some reason, you can use
230:meth:`wx.Window.SetExtraStyle` (``wx.WS_EX_BLOCK_EVENTS``) explicitly
231to prevent the events from being propagated beyond the given window or
232unset this flag for the dialogs that have it on by default.
233
234Typically events that deal with a window as a window (size, motion,
235paint, mouse, keyboard, etc.) are sent only to the window.  Events
236that have a higher level of meaning or are generated by the window
237itself (button click, menu select, tree expand, etc.)  are command
238events and are sent up to the parent to see if it is interested in the
239event. More precisely, as said above, all event classes not deriving
240from :ref:`wx.CommandEvent` (see the :ref:`wx.Event` inheritance
241diagram) do not propagate upward.
242
243In some cases, it might be desired by the programmer to get a certain
244number of system events in a parent window, for example all key events
245sent to, but not used by, the native controls in a dialog. In this
246case, a special event handler will have to be written that will
247override ``ProcessEvent()`` in order to pass all events (or any
248selection of them) to the parent window.
249
250
251.. _event handlers chain:
252
253Event Handlers Chain
254^^^^^^^^^^^^^^^^^^^^
255
256Step 4 of the event propagation algorithm checks for the next
257handler in the event handler chain. This chain can be formed using
258:meth:`wx.EvtHandler.SetNextHandler`:
259
260.. figure:: _static/images/overviews/overview_events_chain.png
261   :align: center
262
263|
264
265(Referring to the image, if ``A.ProcessEvent`` is called and it doesn't
266handle the event, ``B.ProcessEvent`` will be called and so on...).
267
268Additionally, in the case of :ref:`wx.Window` you can build a stack
269(implemented using :ref:`wx.EvtHandler` double-linked list) using
270:meth:`wx.Window.PushEventHandler`:
271
272.. figure:: _static/images/overviews/overview_events_winstack.png
273   :align: center
274
275|
276
277
278
279(Referring to the image, if ``W.ProcessEvent`` is called, it
280immediately calls ``A.ProcessEvent``; if nor A nor B handle the event,
281then the :ref:`wx.Window` itself is used -- i.e. the dynamically bind
282event handlers and static event table entries of :ref:`wx.Window` are
283looked as the last possibility, after all pushed event handlers were
284tested).
285
286By default the chain is empty, i.e. there is no next handler.
287
288
289.. _custom event summary:
290
291Custom Event Summary
292--------------------
293
294General approach
295^^^^^^^^^^^^^^^^
296
297Custom event classes allow you to create more polished-seeming
298controls by allowing the control's user to process updates without
299needing to sub-class the control. However, to effectively use events,
300you normally need to create custom event classes.
301
302This recipe gives you some boilerplate code for creating your own
303custom event classes::
304
305	import wx
306	import wx.lib.newevent
307
308	SomeNewEvent, EVT_SOME_NEW_EVENT = wx.lib.newevent.NewEvent()
309	SomeNewCommandEvent, EVT_SOME_NEW_COMMAND_EVENT = wx.lib.newevent.NewCommandEvent()
310
311
312You can bind the events normally via either binding syntax::
313
314	self.Bind(EVT_SOME_NEW_EVENT, self.handler)
315	EVT_SOME_NEW_EVENT(self, self.handler)
316
317
318You can also attach arbitrary data to the event during its creation,
319then post it to whatever window you choose::
320
321	    # Create the event
322	    evt = SomeNewEvent(attr1="hello", attr2=654)
323	    # Post the event
324	    wx.PostEvent(target, evt)
325
326
327When handling events with such arbitrary data, you can fetch the data
328via attributes, named the same as the names passed in during the event
329instance creation. That is, given the two keyword arguments passed to
330``SomeNewEvent`` above::
331
332
333	    def handler(self, evt):
334		# Given the above constructed event, the following is true
335		evt.attr1 == "hello"
336		evt.attr2 == 654
337
338
339
340
341Miscellaneous Notes
342-------------------
343
344
345.. _user generated events vs programmatically generated events:
346
347User Generated Events vs Programmatically Generated Events
348^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
349
350While generically a :ref:`wx.Event` can be generated both by user actions
351(e.g., resize of a :ref:`wx.Window`) and by calls to functions (e.g.,
352:meth:`wx.Window.SetSize`), wxPython controls normally send
353:ref:`wx.CommandEvent` -derived events only for the user-generated
354events. The only exceptions to this rule are:
355
356- :meth:`wx.BookCtrlBase.AddPage` No event-free alternatives
357
358- :meth:`wx.BookCtrlBase.AdvanceSelection` No event-free alternatives
359
360- :meth:`wx.BookCtrlBase.DeletePage` No event-free alternatives
361
362- :meth:`wx.Notebook.SetSelection`: Use :meth:`wx.Notebook.ChangeSelection`
363  instead, as :meth:`wx.Notebook.SetSelection` is deprecated
364
365- :meth:`wx.TreeCtrl.Delete`: No event-free alternatives
366
367- :meth:`wx.TreeCtrl.DeleteAllItems`: No event-free alternatives
368
369- :meth:`wx.TreeCtrl.EditLabel`: No event-free alternatives
370
371- All :ref:`wx.TextCtrl` methods
372
373
374:meth:`wx.TextEntry.ChangeValue` can be used instead of
375:meth:`wx.TextEntry.SetValue` but the other functions, such as
376:meth:`wx.TextEntry.Replace` or :meth:`wx.TextCtrl.WriteText` don't
377have event-free equivalents.
378
379
380
381.. _window identifiers:
382
383Window Identifiers
384^^^^^^^^^^^^^^^^^^
385
386Window identifiers are integers, and are used to uniquely determine
387window identity in the event system (though you can use it for other
388purposes). In fact, identifiers do not need to be unique across your
389entire application as long they are unique within the particular
390context you're interested in, such as a frame and its children. You
391may use the ``wx.ID_OK`` identifier, for example, on any number of
392dialogs as long as you don't have several within the same dialog.
393
394If you pass ``wx.ID_ANY`` or -1 to a window constructor, an identifier
395will be generated for you automatically by wxPython. This is useful
396when you don't care about the exact identifier either because you're
397not going to process the events from the control being created or
398because you process the events from all controls in one place (in
399which case you should specify ``wx.ID_ANY`` in the
400:meth:`wx.EvtHandler.Bind` call as well). The automatically generated
401identifiers are always negative and so will never conflict with the
402user-specified identifiers which must be always positive.
403
404.. seealso:: See :ref:`Standard event identifiers <standard event identifiers>`
405   for the list of standard identifiers available.
406
407
408You can use ``wx.ID_HIGHEST`` to determine the number above which it is
409safe to define your own identifiers. Or, you can use identifiers below
410``wx.ID_LOWEST``.  Finally, you can allocate identifiers dynamically
411using :func:`wx.NewIdRef` function too. If you use :func:`wx.NewIdRef`
412consistently in your application, you can be sure that your
413identifiers don't conflict accidentally.
414