Shortcut auto repeat release

So I made a extension with a action:

def createActions(self, window):
    action_key_1_minus = window.createAction(EXTENSION_ID+"_key_1_minus", "P. Key 1 Minus", "tools/scripts")
    action_key_1_minus.triggered.connect(self.KEY_1_Minus)

With this shortcut I tend to press and make it autorepeat the command several times until I am good.

However i wanted to detect when I release my shortcut to do another command entirely something like keyRelease.

AFAIK: there is no good way to capture key press / release events of QAction’s QShortCut.

But here is Application global hook for capturing a key press & release, also auto repeat flag is detected. (it would be better to hook Krita’s main window or some other child widget…)

_target_key is set to Qt.Key_F10 just for example. (trying to avoid clashes)

from PyQt5.QtCore import (
        Qt,
        pyqtSignal as QSignal,
        QObject,
        QEvent,
        QCoreApplication)

from PyQt5.QtGui import (
        QCursor,)

from PyQt5.QtWidgets import (
        QToolTip,)


class Hook(QObject):
    _target_key = Qt.Key_F10

    key_press = QSignal(bool)
    key_release = QSignal(bool)

    def eventFilter(self, obj, e):
        e_type = e.type()
        if (e_type == QEvent.KeyPress) and (e.key() == self._target_key):
            self.key_press.emit(e.isAutoRepeat())
            return False  # don't eat event
        elif (e_type == QEvent.KeyRelease) and (e.key() == self._target_key):
            self.key_release.emit(e.isAutoRepeat())
            return False  # don't eat event
        return super().eventFilter(obj, e)

def on_key_press(is_auto_repeat):
    QToolTip.showText(QCursor.pos(), f'key was pressed {is_auto_repeat=}')

def on_key_release(is_auto_repeat):
    # auto repeat release, is a bit hard to see
    QToolTip.showText(QCursor.pos(), f'key was released {is_auto_repeat=}')


hook = Hook()
app = QCoreApplication.instance()

# application global hook, ALL events of application will go through hook. (slows down application)
# try to keep hook installed only when needed, and other times keep unistalled.
app.installEventFilter(hook)
hook.key_press.connect(on_key_press)
hook.key_release.connect(on_key_release)

# Warning: for each installEventFilter() call there should be matching removeEventFilter()
# removeEventFilter is excluded from example. (no good place to put it...)

# app.removeEventFilter(hook)

/AkiR

1 Like