Phoenix icon indicating copy to clipboard operation
Phoenix copied to clipboard

[Request] Add __event_handler__

Open komoto48g opened this issue 3 years ago • 0 comments

Operating system: Windows 10 wxPython version & source: 4.1.1 (pip) Python version & source: 3.9.9

Description of the problem: This is not a problem, but an enhancement of wx.Bind function.

This proposal makes users get all event handlers bound to all widgets in their application. Developers can use it to extend tools such as wx.lib.eventwatcher and debug tools in the future. Users can also write event binding in a more pythonic way, such as @widget.Bind(binder).

The code to change is as follows (This file 'core.py' is generated by wxPython's SIP generator):

C:/Python39/Lib/site-packages/wx/core.py:1428:
def _EvtHandler_Bind(self, event, handler, source=None, id=wx.ID_ANY, id2=wx.ID_ANY):
C:/Python39/Lib/site-packages/wx/core.py:1462:
def _EvtHandler_Unbind(self, event, source=None, id=wx.ID_ANY, id2=wx.ID_ANY, handler=None):

The changes are as follows:

Code Example (click to expand)
    from wx import core # PY3 only
    
    def _EvtHandler_Bind(self, event, handler=None, source=None, id=wx.ID_ANY, id2=wx.ID_ANY):
        assert isinstance(event, wx.PyEventBinder)
        assert source is None or hasattr(source, 'GetId')
        if handler is None:
            return lambda f: _EvtHandler_Bind(self, event, f, source, id, id2)
        if source is not None:
            id  = source.GetId()
        event.Bind(self, id, id2, handler)
        ## record all handlers: single state machine
        if not hasattr(self, '__event_handler__'):
            self.__event_handler__ = {}
        if event.typeId not in self.__event_handler__:
            self.__event_handler__[event.typeId] = [handler]
        else:
            self.__event_handler__[event.typeId].insert(0, handler)
        return handler
    core.EvtHandler.Bind = _EvtHandler_Bind
    del _EvtHandler_Bind

    def _EvtHandler_Unbind(self, event, source=None, id=wx.ID_ANY, id2=wx.ID_ANY, handler=None):
        if source is not None:
            id  = source.GetId()
        retval = event.Unbind(self, id, id2, handler)
        ## remove the specified handler or all handlers
        if retval:
            try:
                actions = self.__event_handler__[event.typeId]
                if handler is None:
                    actions.clear()
                else:
                    actions.remove(handler)
                if not actions:
                    del self.__event_handler__[event.typeId]
            except Exception:
                pass
        return retval
    core.EvtHandler.Unbind = _EvtHandler_Unbind
    del _EvtHandler_Unbind

cf. https://discuss.wxpython.org/t/the-way-to-hack-event-handlers/35643

komoto48g avatar Jan 16 '22 09:01 komoto48g