Certain shortcut key-sequences don't trigger shortcuts when pressed in PyQT5

Viewed 372

Here is some code that reproduces my 'error' so to speak:

import sys


from PyQt5.QtCore import Qt
from PyQt5.QtGui import  QKeySequence
from PyQt5.QtWidgets import (QShortcut, QTextEdit, QApplication)


app = QApplication([])
wid = QTextEdit()

wid.show()
short = QShortcut(QKeySequence(Qt.Key_F2), wid)
short.activated.connect(sys.exit)
app.exec()

Hitting F2 , as expected, shuts the program down. If I were to use other keys as an argument, such as QKeySequence(Qt.Key_Control) or QKeySequence(Qt.Key_Control + Qt.Key_F2), nothing happens when I hit said keys upon launching the program

I can't seem to figure out what about them prevents them from triggering the shortcut. From the reading on other SO threads I've gone through about shortcuts, some state that the widget in question might not be focused. I've made sure my widgets were focused , but despite that, the shortcuts don't trigger when I use such keys

Some state that a widget's child's keyPressEvent might eat up the shortcut. This confuses me. I did go through the docs, and shortcutEvents happen to be their own unique individual event. I don't understand why a widget's keyPressEvent handler might choose to handle a shortcutEvent passed to it

I believe it has something to do with the keys I specified for the shortcuts themselves, but I can't quite put my finger on it. Sure, just using F2 as the shortcut IS an option, but I'd really like to allow for the pressing of say, Shift + F2 or Control + F2 as a shortcut, which isn't working for some odd reason

2 Answers

First of all, shortcuts can be created with strings:

short = QShortcut(QKeySequence('ctrl+f2'), wid)

That said, I believe you don't understand what keyboard modifiers are and how UI interaction works.

In the comments you asked: "a key sequence consisting of JUST Qt.CTRL doesn't seem to work".

The Shift, Alt and Ctrl are modifier keys, which in UI environments are not keys that can trigger anything on their own. They modify the behavior of the other keys.

Most importantly, all those keys are very important in a widget that accepts user input (especially text), and it doesn't make a lot of sense to trigger an action with a key that might be necessary for the basic widget purpose (what if the user just wants to make a clipboard operation and you trigger the quit with Ctrl?).

Then you also ask "Why doesn't JUST 1 as a shortcut work?".
Same concept as above: "1" is a type-able character, why would you prevent writing 1 and quit the program with that?

Keyboard shortcuts should almost always be based on keyboard combinations of modifiers and letter keys, with the only exception of function keys and special keys that can be triggered safely without involving text input.

Note: don't use sys.exit in Qt signals or related functions unless you know what you're doing. Use QApplication.quit.

Changing part of the key sequence to Qt.CTRL worked for me; so perhaps something wrong with Qt.Key_Controlin the sequence.Qt.SHIFT doesnt seem to work for QTextEdit or QLineEdit but does with other widgets. Perhaps use a QWidget as a container and use the keysequence on that rather than QTextEdit widget alone. Otherwise; subclass QTextEdit and overwrite keyPressEvent

import sys


from PyQt5.QtCore import Qt
from PyQt5.QtGui import  QKeySequence
from PyQt5.QtWidgets import (QShortcut, QWidget, QGridLayout, QTextEdit, QApplication)


app = QApplication([])

wid = QWidget()
layout=QGridLayout(wid)
tEdit=QTextEdit()
layout.addWidget(tEdit)
wid.show()
short = QShortcut(QKeySequence(Qt.SHIFT+Qt.Key_P), wid)
#short = QShortcut(QKeySequence(Qt.CTRL+Qt.Key_F2), wid)
#short = QShortcut(QKeySequence(Qt.SHIFT+Qt.Key_1), wid) - doesnt work on textedit/lineedit but works on other widgets
short.activated.connect(sys.exit)
wid.setFocus() #simulate focus on widget
app.exec()
Related