python - 注册 Key_acute 事件在第一次按键时不起作用
问题描述
我正在使用 Qt 5(具体为 PyQt5)并想检查按键。
我遇到的问题是Qt::Key_acute
事件未在第一次按下按钮时注册。
我使用德语键盘布局[1],也许这是我不知道的问题,但我仍然想工作,因为我知道它适用于其他程序(非 Qt)。
当按下Key_acute
键时(在链接的图像中,退格键的左侧),第一次按下时没有任何反应,但是当我再次按下它时,我得到两个事件打印到控制台:180
和0
(180 = 0x0b4 = Key_acute)。
如何捕获此键的第一个按键事件?
PyQt5 程序示例:
import sys
from PyQt5.QtWidgets import *
class App(QWidget):
def __init__(self, argv):
super().__init__()
self.box = QLabel(self)
self.show()
def keyPressEvent(self, ev):
print(ev.key())
self.box.setText(str(ev.key()))
self.box.adjustSize()
super().keyPressEvent(ev)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App(sys.argv)
sys.exit(app.exec_())
[1] https://upload.wikimedia.org/wikipedia/commons/3/36/KB_Germany.svg
解决方案
大多数键盘中的 [ ´ ] 键是“死键”,这是一种特殊的键,等待后面的“组合”实际字符。
据我所知,您只能将这些键作为发布事件,而不是新闻事件。
当某些死键被按下两次时,它们不会作为按键/释放事件发送,但您可以将它们event()
作为QEvent.InputMethod
类型拦截。
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
keyNameFromValue = {}
keyNameFromString = {}
for k, v in vars(Qt).items():
if isinstance(v, Qt.Key):
keyNameFromValue[v] = k
keyNameFromString[QKeySequence(v).toString()] = k
class App(QWidget):
def __init__(self, argv):
super().__init__()
layout = QVBoxLayout(self)
self.box = QLabel(self)
layout.addWidget(self.box)
self.show()
def event(self, ev):
if ev.type() == QEvent.InputMethod:
s = ev.commitString()
if s:
self.box.setText('InputMethod > {}: {}'.format(
keyNameFromString.get(s, '(Unknown)'), s))
self.box.adjustSize()
return super().event(ev)
def keyPressEvent(self, ev):
if not ev.isAutoRepeat():
self.box.setText('KeyPress > {}: {}'.format(
keyNameFromValue.get(ev.key()), ev.text()))
self.box.adjustSize()
super().keyPressEvent(ev)
def keyReleaseEvent(self, ev):
if not ev.isAutoRepeat():
self.box.setText('KeyRelease > {}: {}'.format(
keyNameFromValue.get(ev.key()), ev.text()))
self.box.adjustSize()
super().keyReleaseEvent(ev)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
ex = App(sys.argv)
sys.exit(app.exec_())
在这种情况下,第一次按下 [´] 键的结果是Key_Dead_Acute
(不能直接打印),第二次是Key_acute
.
如果您需要显示可打印的死键应如何显示为字符串,则可以为死键(其中少于 50 个)创建自己的基于字典的映射。不幸的是,没有编程方法可以做到这一点,因为即使对于“相同”字符,它们的字符串转换也不同,并且名称或值
之间没有实际的相关性:例如,虽然对应于,变成。Qt.Key_Dead_*
Qt.Key_*
Qt.Key_Dead_Acute
Qt.Key_acute
Qt.Key_Dead_Grave
Qt.Key_QuoteLeft
推荐阅读
- mysql - 字段列表中的未知列“r”
- flutter - Flutter 导航如何移动到每个项目的第二页
- python - Pandas read_sql 列不正确
- docker - 如何在 VSCode 开发容器中使用 USB/COM 端口?
- php - 错误:运行 composer install 时“提取 zip 文件需要 ZipArchive”;与流行!_OS 21 宇宙
- flutter - 颤振通道主错误请在切换分支之前提交您的更改或存储它们
- php - 如何更改实体默认显示视图上的数据
- node.js - 如何在 Github 中指定操作/设置节点的路径
- javascript - 如何在 vue 中使用打字稿
- regex - 提取以字符串编码的长度字符串的正则表达式