.. include:: headings.inc .. _EvtHandler: ========================================================================================================================================== |phoenix_title| **EvtHandler** ========================================================================================================================================== A class that can handle events from the windowing system. :ref:`Window` is (and therefore all window classes are) derived from this class. When events are received, :ref:`EvtHandler` invokes the method listed in the event table using itself as the object. When using multiple inheritance **it is imperative that the** :ref:`EvtHandler` **(-derived) class is the first class inherited** such that the ``this`` pointer for the overall object will be identical to the ``this`` pointer of the :ref:`EvtHandler` portion. .. seealso:: :ref:`How Events are Processed `, :ref:`EventBlocker`, :ref:`EventLoopBase` | |class_hierarchy| Inheritance Diagram ===================================== Inheritance diagram for class **EvtHandler** .. raw:: html

Inheritance diagram of EvtHandler

| |sub_classes| Known Subclasses ============================== :ref:`AppConsole`, `AuiManager`, `DocManager`, `Document`, :ref:`EventBlocker`, `FileSystemWatcher`, :ref:`Menu`, `MouseEventsManager`, :ref:`adv.NotificationMessage`, :ref:`Process`, `PropertyGridPage`, :ref:`adv.TaskBarIcon`, :ref:`Timer`, :ref:`Validator`, `View`, :ref:`Window` | |method_summary| Methods Summary ================================ ================================================================================ ================================================================================ :meth:`~EvtHandler.__init__` Constructor. :meth:`~EvtHandler.AddFilter` Add an event filter whose FilterEvent() method will be called for each and every event processed by wxWidgets. :meth:`~EvtHandler.AddPendingEvent` Post an event to be processed later. :meth:`~EvtHandler.Bind` Bind an event to an event handler. :meth:`~EvtHandler.DeletePendingEvents` Deletes all events queued on this event handler using :meth:`QueueEvent` or :meth:`AddPendingEvent` . :meth:`~EvtHandler.GetEvtHandlerEnabled` Returns ``True`` if the event handler is enabled, ``False`` otherwise. :meth:`~EvtHandler.GetNextHandler` Returns the pointer to the next handler in the chain. :meth:`~EvtHandler.GetPreviousHandler` Returns the pointer to the previous handler in the chain. :meth:`~EvtHandler.IsUnlinked` Returns ``True`` if the next and the previous handler pointers of this event handler instance are ``None``. :meth:`~EvtHandler.ProcessEvent` Processes an event, searching event tables and calling zero or more suitable event handler function(s). :meth:`~EvtHandler.ProcessEventLocally` Try to process the event in this handler and all those chained to it. :meth:`~EvtHandler.ProcessPendingEvents` Processes the pending events previously queued using :meth:`QueueEvent` or :meth:`AddPendingEvent` ; you must call this function only if you are sure there are pending events for this handler, otherwise a ``CHECK`` will fail. :meth:`~EvtHandler.QueueEvent` Queue event for a later processing. :meth:`~EvtHandler.RemoveFilter` Remove a filter previously installed with :meth:`AddFilter` . :meth:`~EvtHandler.SafelyProcessEvent` Processes an event by calling :meth:`ProcessEvent` and handles any exceptions that occur in the process. :meth:`~EvtHandler.SetEvtHandlerEnabled` Enables or disables the event handler. :meth:`~EvtHandler.SetNextHandler` Sets the pointer to the next handler. :meth:`~EvtHandler.SetPreviousHandler` Sets the pointer to the previous handler. :meth:`~EvtHandler.Unbind` Disconnects the event handler binding for event from self. :meth:`~EvtHandler.Unlink` Unlinks this event handler from the chain it's part of (if any); then links the "previous" event handler to the "next" one (so that the chain won't be interrupted). ================================================================================ ================================================================================ | |property_summary| Properties Summary ===================================== ================================================================================ ================================================================================ :attr:`~EvtHandler.EvtHandlerEnabled` See :meth:`~EvtHandler.GetEvtHandlerEnabled` and :meth:`~EvtHandler.SetEvtHandlerEnabled` :attr:`~EvtHandler.NextHandler` See :meth:`~EvtHandler.GetNextHandler` and :meth:`~EvtHandler.SetNextHandler` :attr:`~EvtHandler.PreviousHandler` See :meth:`~EvtHandler.GetPreviousHandler` and :meth:`~EvtHandler.SetPreviousHandler` ================================================================================ ================================================================================ | |api| Class API =============== .. class:: EvtHandler(Object, Trackable) A class that can handle events from the windowing system. **Possible constructors**:: EvtHandler() .. method:: __init__(self) Constructor. .. staticmethod:: AddFilter(filter) Add an event filter whose FilterEvent() method will be called for each and every event processed by wxWidgets. The filters are called in ``LIFO`` order and :ref:`App` is registered as an event filter by default. The pointer must remain valid until it's removed with :meth:`RemoveFilter` and is not deleted by :ref:`EvtHandler`. :param `filter`: :type `filter`: EventFilter .. versionadded:: 2.9.3 .. method:: AddPendingEvent(self, event) Post an event to be processed later. This function is similar to :meth:`QueueEvent` but can't be used to post events from worker threads for the event objects with `String` fields (i.e. in practice most of them) because of an unsafe use of the same `String` object which happens because the `String` field in the original `event` object and its copy made internally by this function share the same string buffer internally. Use :meth:`QueueEvent` to avoid this. A copy of `event` is made by the function, so the original can be deleted as soon as function returns (it is common that the original is created on the stack). This requires that the :meth:`Event.Clone` method be implemented by event so that it can be duplicated and stored until it gets processed. :param `event`: Event to add to the pending events queue. :type `event`: Event .. method:: Bind(self, event, handler, source=None, id=wx.ID_ANY, id2=wx.ID_ANY) Bind an event to an event handler. :param event: One of the ``EVT_`` objects that specifies the type of event to bind, :param handler: A callable object to be invoked when the event is delivered to self. Pass None to disconnect an event handler. :param source: Sometimes the event originates from a different window than self, but you still want to catch it in self. (For example, a button event delivered to a frame.) By passing the source of the event, the event handling system is able to differentiate between the same event type from different controls. :param id: Used to spcify the event source by ``ID`` instead of instance. :param id2: Used when it is desirable to bind a handler to a range of IDs, such as with ``EVT_MENU_RANGE``. .. method:: DeletePendingEvents(self) Deletes all events queued on this event handler using :meth:`QueueEvent` or :meth:`AddPendingEvent` . Use with care because the events which are deleted are (obviously) not processed and this may have unwanted consequences (e.g. user actions events will be lost). .. method:: GetEvtHandlerEnabled(self) Returns ``True`` if the event handler is enabled, ``False`` otherwise. :rtype: `bool` .. seealso:: :meth:`SetEvtHandlerEnabled` .. method:: GetNextHandler(self) Returns the pointer to the next handler in the chain. :rtype: :ref:`EvtHandler` .. seealso:: :meth:`SetNextHandler` , :meth:`GetPreviousHandler` , :meth:`SetPreviousHandler` , :meth:`Window.PushEventHandler` , :meth:`Window.PopEventHandler` .. method:: GetPreviousHandler(self) Returns the pointer to the previous handler in the chain. :rtype: :ref:`EvtHandler` .. seealso:: :meth:`SetPreviousHandler` , :meth:`GetNextHandler` , :meth:`SetNextHandler` , :meth:`Window.PushEventHandler` , :meth:`Window.PopEventHandler` .. method:: IsUnlinked(self) Returns ``True`` if the next and the previous handler pointers of this event handler instance are ``None``. :rtype: `bool` .. versionadded:: 2.9.0 .. seealso:: :meth:`SetPreviousHandler` , :meth:`SetNextHandler` .. method:: ProcessEvent(self, event) Processes an event, searching event tables and calling zero or more suitable event handler function(s). Normally, your application would not call this function: it is called in the wxWidgets implementation to dispatch incoming user interface events to the framework (and application). However, you might need to call it if implementing new functionality (such as a new control) where you define new event types, as opposed to allowing the user to override virtual functions. Notice that you don't usually need to override :meth:`ProcessEvent` to customize the event handling, overriding the specially provided :meth:`TryBefore` and :meth:`TryAfter` functions is usually enough. For example, :ref:`MDIParentFrame` may override :meth:`TryBefore` to ensure that the menu events are processed in the active child frame before being processed in the parent frame itself. The normal order of event table searching is as follows: - :meth:`App.FilterEvent` is called. If it returns anything but ``-1`` (default) the processing stops here. - :meth:`TryBefore` is called (this is where :ref:`Validator` are taken into account for :ref:`Window` objects). If this returns ``True``, the function exits. - If the object is disabled (via a call to :meth:`EvtHandler.SetEvtHandlerEnabled` ) the function skips to step (7). - Dynamic event table of the handlers bound using :meth:`Bind<>` is searched. If a handler is found, it is executed and the function returns ``True`` unless the handler used :meth:`Event.Skip` to indicate that it didn't handle the event in which case the search continues. - Static events table of the handlers bound using event table macros is searched for this event handler. If this fails, the base class event table is tried, and so on until no more tables exist or an appropriate function was found. If a handler is found, the same logic as in the previous step applies. - The search is applied down the entire chain of event handlers (usually the chain has a length of one). This chain can be formed using :meth:`EvtHandler.SetNextHandler` : .. figure:: _static\images\overviews\overview_events_chain.png :align: center | (referring to the image, if ``A->ProcessEvent`` is called and it doesn't handle the event, ``B->ProcessEvent`` will be called and so on...). Note that in the case of :ref:`Window` you can build a stack of event handlers (see :meth:`Window.PushEventHandler` for more info). If any of the handlers of the chain return ``True``, the function exits. - :meth:`TryAfter` is called: for the :ref:`Window` object this may propagate the event to the window parent (recursively). If the event is still not processed, :meth:`ProcessEvent` on TheApp object is called as the last step. Notice that steps (2)-(6) are performed in :meth:`ProcessEventLocally` which is called by this function. :param `event`: Event to process. :type `event`: Event :rtype: `bool` :returns: ``True`` if a suitable event handler function was found and executed, and the function did not call :meth:`Event.Skip` . .. seealso:: :meth:`SearchEventTable` .. method:: ProcessEventLocally(self, event) Try to process the event in this handler and all those chained to it. As explained in :meth:`ProcessEvent` documentation, the event handlers may be chained in a doubly-linked list. This function tries to process the event in this handler (including performing any pre-processing done in :meth:`TryBefore` , e.g. applying validators) and all those following it in the chain until the event is processed or the chain is exhausted. This function is called from :meth:`ProcessEvent` and, in turn, calls :meth:`TryBefore` and :meth:`TryAfter` . It is not virtual and so cannot be overridden but can, and should, be called to forward an event to another handler instead of :meth:`ProcessEvent` which would result in a duplicate call to :meth:`TryAfter` , e.g. resulting in all unprocessed events being sent to the application object multiple times. :param `event`: Event to process. :type `event`: Event :rtype: `bool` :returns: ``True`` if this handler of one of those chained to it processed the event. .. versionadded:: 2.9.1 .. method:: ProcessPendingEvents(self) Processes the pending events previously queued using :meth:`QueueEvent` or :meth:`AddPendingEvent` ; you must call this function only if you are sure there are pending events for this handler, otherwise a ``CHECK`` will fail. The real processing still happens in :meth:`ProcessEvent` which is called by this function. Note that this function needs a valid application object (see :meth:`AppConsole.GetInstance` ) because :ref:`App` holds the list of the event handlers with pending events and this function manipulates that list. .. method:: QueueEvent(self, event) Queue event for a later processing. This method is similar to :meth:`ProcessEvent` but while the latter is synchronous, i.e. the event is processed immediately, before the function returns, this one is asynchronous and returns immediately while the event will be processed at some later time (usually during the next event loop iteration). Another important difference is that this method takes ownership of the `event` parameter, i.e. it will delete it itself. This implies that the event should be allocated on the heap and that the pointer can't be used any more after the function returns (as it can be deleted at any moment). :meth:`QueueEvent` can be used for inter-thread communication from the worker threads to the main thread, it is safe in the sense that it uses locking internally and avoids the problem mentioned in :meth:`AddPendingEvent` documentation by ensuring that the `event` object is not used by the calling thread any more. Care should still be taken to avoid that some fields of this object are used by it, notably any `String` members of the event object must not be shallow copies of another `String` object as this would result in them still using the same string buffer behind the scenes. For example: :: def FunctionInAWorkerThread(strs): evt = wx.CommandEvent() # NOT evt.SetString(strs) as this would be a shallow copy evt.SetString(strs[:]) # make a deep copy wx.TheApp.QueueEvent(evt) Note that you can use `ThreadEvent` instead of :ref:`CommandEvent` to avoid this problem: :: def FunctionInAWorkerThread(strs): evt = wx.ThreadEvent() evt.SetString(strs) # wx.ThreadEvent.Clone() makes sure that the internal wx.String # member is not shared by other string instances: wx.TheApp.QueueEvent(evt.Clone()) Finally notice that this method automatically wakes up the event loop if it is currently idle by calling :func:`WakeUpIdle` so there is no need to do it manually when using it. :param `event`: A heap-allocated event to be queued, :meth:`QueueEvent` takes ownership of it. This parameter shouldn't be ``NULL`` . :type `event`: Event .. versionadded:: 2.9.0 .. staticmethod:: RemoveFilter(filter) Remove a filter previously installed with :meth:`AddFilter` . It's an error to remove a filter that hadn't been previously added or was already removed. :param `filter`: :type `filter`: EventFilter .. versionadded:: 2.9.3 .. method:: SafelyProcessEvent(self, event) Processes an event by calling :meth:`ProcessEvent` and handles any exceptions that occur in the process. If an exception is thrown in event handler, :meth:`App.OnExceptionInMainLoop` is called. :param `event`: Event to process. :type `event`: Event :rtype: `bool` :returns: ``True`` if the event was processed, ``False`` if no handler was found or an exception was thrown. .. seealso:: :meth:`Window.HandleWindowEvent` .. method:: SetEvtHandlerEnabled(self, enabled) Enables or disables the event handler. :param `enabled`: ``True`` if the event handler is to be enabled, ``False`` if it is to be disabled. :type `enabled`: bool .. note:: You can use this function to avoid having to remove the event handler from the chain, for example when implementing a dialog editor and changing from edit to test mode. .. seealso:: :meth:`GetEvtHandlerEnabled` .. method:: SetNextHandler(self, handler) Sets the pointer to the next handler. :param `handler`: The event handler to be set as the next handler. Cannot be ``None``. :type `handler`: EvtHandler .. note:: See :meth:`ProcessEvent` for more info about how the chains of event handlers are internally used. Also remember that :ref:`EvtHandler` uses double-linked lists and thus if you use this function, you should also call :meth:`SetPreviousHandler` on the argument passed to this function: :: handlerA.SetNextHandler(handlerB) handlerB.SetPreviousHandler(handlerA) .. seealso:: :ref:`How Events are Processed ` .. method:: SetPreviousHandler(self, handler) Sets the pointer to the previous handler. All remarks about :meth:`SetNextHandler` apply to this function as well. :param `handler`: The event handler to be set as the previous handler. Cannot be ``None``. :type `handler`: EvtHandler .. seealso:: :ref:`How Events are Processed ` .. method:: Unbind(self, event, source=None, id=wx.ID_ANY, id2=wx.ID_ANY, handler=None) Disconnects the event handler binding for event from self. Returns True if successful. .. method:: Unlink(self) Unlinks this event handler from the chain it's part of (if any); then links the "previous" event handler to the "next" one (so that the chain won't be interrupted). E.g. if before calling :meth:`Unlink` you have the following chain: .. figure:: _static\images\overviews\evthandler_unlink_before.png :align: center | then after calling B-> :meth:`Unlink` you'll have: .. figure:: _static\images\overviews\evthandler_unlink_after.png :align: center | .. versionadded:: 2.9.0 .. attribute:: EvtHandlerEnabled See :meth:`~EvtHandler.GetEvtHandlerEnabled` and :meth:`~EvtHandler.SetEvtHandlerEnabled` .. attribute:: NextHandler See :meth:`~EvtHandler.GetNextHandler` and :meth:`~EvtHandler.SetNextHandler` .. attribute:: PreviousHandler See :meth:`~EvtHandler.GetPreviousHandler` and :meth:`~EvtHandler.SetPreviousHandler`