Is there a way with wxPython 4 to recognize double pressing the same key? Especially in my case, I would like to recognize when the SHIFT key is pressed twice in quick succession.
Here is a more general solution
The event EVT_CHAR_HOOK
is used instead of EVT_KEY_UP
. The problem with EVT_KEY_UP
is that it is swallowed when the event is bound to a frame that contains a panel.
The challenge with EVT_CHAR_HOOK
is to determine whether the key is actually pressed twice or only held. Therefore the RawKeyFlags are read out. The bit at position 30 indicates whether the key was held or not.
Please note, however, that this solution only works on Windows systems!
import wx
class DoubleKeyStrokeListener(object):
def __init__(self, parent, keyCode, callback, timeout=500):
self._monitoredKey = keyCode
self._callback = callback
self._timeout = timeout
self._firstPressRecognized = False
self._keyTimer = wx.Timer(parent)
parent.Bind(wx.EVT_CHAR_HOOK, self._OnKeyPressed)
parent.Bind(wx.EVT_TIMER, self._OnTimer, self._keyTimer)
def _OnKeyPressed(self, event):
event.Skip()
pressedKey = event.GetKeyCode()
if pressedKey == self._monitoredKey:
rawFlags = event.GetRawKeyFlags()
# bit at position 30 is "previous key state" flag
prevStateBit = rawFlags >> 30 & 1
if prevStateBit == 1: # -> key is held
return
if self._firstPressRecognized:
self._firstPressRecognized = False
self._callback(event)
else:
self._firstPressRecognized = True
self._keyTimer.StartOnce(self._timeout)
else:
self._firstPressRecognized = False
def _OnTimer(self, event):
self._firstPressRecognized = False
event.Skip()