Search code examples
pythoneventswxpythonspinnerwxwidgets

How to get end of spinning event with wxPython


I have a SpinCtrl on my window and want to process a spin event only on mouse up or arrow key up (end of spinning). Because there is no event like this, I wanted to use a mouse event. But if I bind EVT_LEFT_DOWN and EVT_LEFT_UP, EVT_SPIN is not sent anymore and the control does nothing.

How can I perceive an end of spinning event with a SpinCtrl? Is it possible to call the default event handler on EVT_LEFT_DOWN and the other events?


Solution

  • Who's interested: I got a solution:

    class SpinEndEventManager(object):
        def __init__(self):
            self._controls = []
            self._event_handlers = []
            self._has_spinned = False
    
        def add(self, control, event_handler):
            self._controls.append(control)
            self._event_handlers.append(event_handler)
            control.Bind(wx.EVT_SPINCTRL, self._on_event)
            control.Bind(wx.EVT_LEFT_UP, self._on_event)
            control.Bind(wx.EVT_KEY_DOWN, self._on_event)
            control.Bind(wx.EVT_KEY_UP, self._on_event)
    
        def _on_event(self, event):
            is_spin_end_event = False
            event_type = event.GetEventType()
            control = event.GetEventObject()
            if event_type == wx.wxEVT_COMMAND_SPINCTRL_UPDATED:
                self._has_spinned = True
            elif event_type == wx.wxEVT_LEFT_UP:
                if self._has_spinned:
                    is_spin_end_event = True
                event.Skip()
            elif event_type == wx.wxEVT_KEY_DOWN:
                key = event.GetKeyCode()
                old_value = control.GetValue()
                if key == wx.WXK_UP:
                    value = old_value + 1
                elif key == wx.WXK_DOWN:
                    value = old_value - 1
                control.SetValue(value)
                value = control.GetValue()
                if value != old_value:
                    self._has_spinned = True
                if key == wx.WXK_DOWN:
                    value_string_length = len(str(value))
                    control.SetSelection(value_length, value_string_length)
            elif event_type == wx.wxEVT_KEY_UP:
                if self._has_spinned:
                    is_spin_end_event = True
            if is_spin_end_event:
                self._has_spinned = False
                index = self._controls.index(control)
                self._event_handlers[index](event)