获取任何QKeyEvent键值

时间:2018-06-14 06:57:00

标签: python qt pyqt pyqt5 keyboard-events

我正在使用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?

1 个答案:

答案 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_())