Регистрация события Key_acute не работает при первом нажатии клавиши - PullRequest
0 голосов
/ 25 января 2020

Я использую Qt 5 (указать PyQt5 c) и хочу проверить нажатие клавиши.

У меня проблема в том, что событие 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

1 Ответ

0 голосов
/ 26 января 2020

Клавиша [´] на большинстве клавиатур представляет собой « мертвую клавишу », особый вид клавиши, которая ожидает следующего, чтобы «составить» фактический символ.

Насколько насколько я знаю, эти клавиши можно получить только как событие отпускания, а не событие нажатия.

Когда некоторые мертвые клавиши нажимаются дважды, они не отправляются как события нажатия / отпускания клавиш. , но они могут быть перехвачены с 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_* или значения: например, пока * 102 3 * соответствует Qt.Key_acute, Qt.Key_Dead_Grave становится Qt.Key_QuoteLeft.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...