我正在使用 PyQt5。当我编写一个 keyPressEvent 处理程序时,出于调试目的,我希望能够打印出关于按下了哪些键的人类可读的描述。无论事件中按下了多少键,或者它们是修饰符还是“常规”键,我都希望能够打印这样的东西。
我看过this previous question其中接受的答案(使用 C++)建议创建一个 QKeySequence 并使用它的 .toString
方法。我可以这样做:
def keyPressEvent(self, event):
print("got a key event of ", QKeySequence(event.key()).toString())
但是,这并不总是有效。例如,如果我按下 Shift 键,当我尝试输出(或者如果我尝试将其编码为 UTF-8)时会导致编码错误。这似乎是因为 QKeySequence 不适用于孤立的修饰键:
>>> QKeySequence(Qt.Key_Shift).toString().encode('unicode-escape')
b'\\u17c0\\udc20'
它给出了胡言乱语,而不是我所期望的,即“Shift”。如果我使用
Qt.SHIFT
就可以了(有点,因为它给出了“Shift+”),但这没有用,因为 Qt.SHIFT
不是我得到的event.key()
如果我按下 Shift 键。我怎样才能让 Qt 给我一个可打印的表示任何可能是
event.key()
的值的东西, 其中 event
是 QKeyEvent 吗?
最佳答案
处理具体问题:
How can I get Qt to give me a printable representation of anything that might ever be the value of event.key(), where event is a QKeyEvent?
首先要注意的是
event.key()
返回 int
,而不是 Qt.Key
.这仅仅是因为 key 可以是任何 unicode 值。因此,给出任何字面上的可打印表示实际上是不可行的,因为并非每个 unicode 键都是可打印的,并且枚举它们是不切实际的。Qt 提供的唯一 API 是
QKeySequnce
类(class)。但是,正如您所发现的,它不会以您想要的方式处理所有输入。因此,您将不得不推出自己的解决方案。使用
QMetaEnum
可能很诱人尽可能将键值转换为其名称。但是,这在这里不起作用,因为没有 staticMetaObject
对于Qt
对象,而 PyQt 不提供像 qt_getQtMetaObject
这样的东西。 .它目前也没有实现 QMetaEnum.fromType
(尽管这可能会在 future 的版本中改变)。因此,唯一可用的解决方案是使用普通的 python 内省(introspection)来构建映射,并从中构建可打印的表示。
这是一个基本的演示(仅在 Linux 上测试):
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget
keymap = {}
for key, value in vars(Qt).items():
if isinstance(value, Qt.Key):
keymap[value] = key.partition('_')[2]
modmap = {
Qt.ControlModifier: keymap[Qt.Key_Control],
Qt.AltModifier: keymap[Qt.Key_Alt],
Qt.ShiftModifier: keymap[Qt.Key_Shift],
Qt.MetaModifier: keymap[Qt.Key_Meta],
Qt.GroupSwitchModifier: keymap[Qt.Key_AltGr],
Qt.KeypadModifier: keymap[Qt.Key_NumLock],
}
def keyevent_to_string(event):
sequence = []
for modifier, text in modmap.items():
if event.modifiers() & modifier:
sequence.append(text)
key = keymap.get(event.key(), event.text())
if key not in sequence:
sequence.append(key)
return '+'.join(sequence)
class Window(QWidget):
def keyPressEvent(self, event):
print(keyevent_to_string(event))
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Window()
window.setGeometry(600, 100, 300, 200)
window.show()
sys.exit(app.exec_())
关于python - 获取任何 QKeyEvent 键值的可打印名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50851350/