Last active
August 21, 2022 20:42
-
-
Save Sl-Alex/20bace0271a59c8b6db446c3faacefb0 to your computer and use it in GitHub Desktop.
Extension of QLineEdit with a possibility to catch shortcuts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from PyQt5.QtWidgets import QLineEdit | |
from PyQt5 import QtCore | |
from PyQt5.QtCore import Qt | |
""" Extension of QLineEdit with a possibility to catch shortcuts. | |
Standard QKeySequenceEdit is too slow and does not make any difference between numpad and normal keys. | |
""" | |
class ShortcutEdit(QLineEdit): | |
"""This signal is emitted whenever a new key or modifier is pressed | |
First parameteris the key (can be zero), second is a list of modifiers | |
""" | |
shortcutChanged = QtCore.pyqtSignal(int, list) | |
keymap = {} | |
modmap = {} | |
modkeyslist = [] | |
current_modifiers = [] | |
current_key = 0 | |
def __init__(self, *args, **kwargs): | |
super().__init__(*args, **kwargs) | |
for key, value in vars(Qt).items(): | |
if isinstance(value, Qt.Key): | |
self.keymap[value] = key.partition('_')[2] | |
self.modmap = { | |
Qt.ControlModifier: 'Ctrl', | |
Qt.AltModifier: 'Alt', | |
Qt.ShiftModifier: 'Shift', | |
Qt.MetaModifier: 'Meta', | |
Qt.GroupSwitchModifier: 'AltGr', | |
Qt.KeypadModifier: 'Num', | |
} | |
self.modkeyslist = [ | |
Qt.Key_Control, | |
Qt.Key_Alt, | |
Qt.Key_Shift, | |
Qt.Key_Meta, | |
Qt.Key_AltGr, | |
Qt.Key_NumLock, | |
] | |
self.installEventFilter(self) | |
def eventFilter(self, object, event): | |
if event.type() == QtCore.QEvent.KeyPress: | |
# Ignore empty events, report "processed" | |
if event.key() == 0 and int(event.modifiers()) == 0: | |
return True | |
# Reset the state | |
self.current_modifiers = [] | |
self.current_key = 0 | |
# Extract event key and modifiers | |
key = event.key() | |
modifiers = int(event.modifiers()) | |
# Prepare a map with the current modifiers (a copy of self.modmap with only active modifiers) | |
modifiers_dict = {} | |
for modifier in self.modmap.keys(): | |
if modifiers & modifier: | |
modifiers_dict[modifier] = self.modmap[modifier] | |
# Invalidate the key (it is already in the modifiers list anyway) | |
if key in self.modkeyslist: | |
key = 0 | |
text = '' | |
# First, add all modifiers | |
for modifier in modifiers_dict: | |
if text != '': | |
text = text + '+' | |
text = text + modifiers_dict[modifier] | |
self.current_modifiers.append(modifier) | |
# Special case for numpad keys, print them like NumMinus or Num5, without separator | |
if Qt.KeypadModifier in modifiers_dict and key != 0: | |
text = text + self.keymap[key] | |
self.current_key = key | |
# Normal keys | |
elif key in self.keymap: | |
if text != '': | |
text = text + '+' | |
text = text + self.keymap[key] | |
self.current_key = key | |
# Update the text and emit a signal | |
self.setText(text) | |
self.shortcutChanged.emit(self.current_key, self.current_modifiers) | |
return True | |
elif event.type() == QtCore.QEvent.KeyRelease: | |
return True | |
return False |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment