我正在使用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()
{1}}如果我按下Shift键。
如何让Qt为我提供任何的可打印表示, 可能<{1}},其中event.key()
是event
一个QKeyEvent?
答案 0 :(得分:1)
处理具体问题:
我怎样才能让Qt给我一个可打印的任何表示 这可能是event.key()的值,其中event是a QKeyEvent?
首先要注意的是,event.key()
会返回int
,而不是Qt.Key
。这只是因为密钥可以任何unicode值。作为这一点的结果,给出字面上任何的可打印表示并不是真的可行,因为并非每个unicode键都是可打印的,并且将它们全部枚举是不切实际的。
Qt提供的唯一API是QKeySequnce
类。但是,正如您所发现的,它不会以您希望的方式处理所有输入。所以你必须推出自己的解决方案。
尽可能使用QMetaEnum
将键值转换为其名称可能很诱人。但是,这在此处不起作用,因为staticMetaObject
对象没有Qt
,而PyQt不提供qt_getQtMetaObject
之类的内容。它目前还没有实现QMetaEnum.fromType
(尽管在将来的版本中可能会有所改变)。
所以唯一可用的解决方案是使用普通的python内省来构建映射,并从中构建一个可打印的表示。
这是一个基本演示(仅在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_())