Skip to content

Instantly share code, notes, and snippets.

@Sl-Alex
Last active August 21, 2022 20:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Sl-Alex/20bace0271a59c8b6db446c3faacefb0 to your computer and use it in GitHub Desktop.
Save Sl-Alex/20bace0271a59c8b6db446c3faacefb0 to your computer and use it in GitHub Desktop.
Extension of QLineEdit with a possibility to catch shortcuts
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