В PyQt, как распечатать "Ctrl+ ключ" в QLineEdit при нажатии Ctrl + anyKey

Здесь мой код, где я генерировал событие для QLineEdit, чтобы поместить комбинацию нажатой клавиши в текстовую строку, это хорошо для клавиш Shift и Alt, но не для клавиши Ctrl, почему?

#!/usr/bin/python

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

def main():
    app = QApplication(sys.argv)
    w = MyWindow()
    w.show()
    sys.exit(app.exec_())
class MyWindow(QWidget):
    def __init__(self, *args):
        QWidget.__init__(self, *args)

        self.la = QLabel("Press tab in this box:")
        self.le = MyLineEdit()


        layout = QVBoxLayout()
        layout.addWidget(self.la)
        layout.addWidget(self.le)
        self.setLayout(layout)


        self.connect(self.le, SIGNAL("press"),
                 self.update)

    def update(self):
        oldText = str(self.le.text())
        self.le.setText(self.le.myText)

class MyLineEdit(QLineEdit):
    def __init__(self, *args):
        QLineEdit.__init__(self, *args)

        self.myText = ""
    def event(self, event):
        if event.type() == QEvent.KeyPress:
            if  event.modifiers() & Qt.ControlModifier  :

в текстовой строке это нормально для клавиш Shift и Alt, я могу поставить переменную self.myText в текстовой строке, но не для клавиши Ctrl, почему?

                print event.text()
                self.myText = "Ctrl+"+ event.text()
                self.emit(SIGNAL("press"))
            return True
        return QLineEdit.event(self, event)

if __name__ == "__main__":
    main()

2 ответа

Решение

Причина, по которой оригинальный пример не работает, заключается в том, что многие комбинации клавиш Ctrl+ производят управляющие символы - например, Ctrl+J создает новую строку.

Правильный способ захвата комбинаций клавиш - использование QKeySequence, которое будет работать для всех клавиш, включая функциональные клавиши, клавиши со стрелками, клавиши перемещения вверх / вниз и т. Д. Вы также можете получить переведенные сочетания клавиш с помощью QKeySequence.PortableText.

Вот демонстрация, основанная на оригинальном примере:

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

def main():
    app = QApplication(sys.argv)
    w = MyWindow()
    w.show()
    sys.exit(app.exec_())

class MyWindow(QWidget):
    def __init__(self, *args):
        QWidget.__init__(self, *args)

        self.la = QLabel("Press tab in this box:")
        self.le = MyLineEdit()

        layout = QVBoxLayout()
        layout.addWidget(self.la)
        layout.addWidget(self.le)
        self.setLayout(layout)

        self.le.keyPressed.connect(self.update)

    def update(self, text):
        self.le.setText(text)

MOD_MASK = (Qt.CTRL | Qt.ALT | Qt.SHIFT | Qt.META)

class MyLineEdit(QLineEdit):
    keyPressed = pyqtSignal(str)

    def keyPressEvent(self, event):
        keyname = ''
        key = event.key()
        modifiers = int(event.modifiers())
        if (modifiers and modifiers & MOD_MASK == modifiers and
            key > 0 and key != Qt.Key_Shift and key != Qt.Key_Alt and
            key != Qt.Key_Control and key != Qt.Key_Meta):

            keyname = QKeySequence(modifiers + key).toString()

            print('event.text(): %r' % event.text())
            print('event.key(): %d, %#x, %s' % (key, key, keyname))

        self.keyPressed.emit(keyname)

if __name__ == "__main__":
    main()

Это возможно, когда мы используем метод key(), который возвращает значение ключа int, тогда мы просто конвертируем int в char, используя функцию unichr()

class MyLineEdit(QLineEdit):
    def __init__(self, *args):
        QLineEdit.__init__(self, *args)

    def event(self, event):
        self.myText = ""
        event_key = ""
        if event.type() == QEvent.KeyPress:
            if event.text() != "" :
                event_key = str(unichr(event.key())).lower()
            if event.modifiers()==  Qt.ControlModifier  :
                print event.text()
                self.myText = "Ctrl+" + event_key
            self.emit(SIGNAL("press"))
            return True
        return QLineEdit.event(self, event)
Другие вопросы по тегам