在pyqt中按下Ctrl + anyKey时如何在QLineEdit中打印“Ctrl + key”

Posted

技术标签:

【中文标题】在pyqt中按下Ctrl + anyKey时如何在QLineEdit中打印“Ctrl + key”【英文标题】:in pyqt how to print "Ctrl+key" in QLineEdit when pressed Ctrl + anyKey 【发布时间】:2016-01-27 09:15:28 【问题描述】:

这里是我的代码,我为 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()

【问题讨论】:

【参考方案1】:

原始示例不起作用的原因是许多 Ctrl+key 组合产生控制字符 - 例如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()

【讨论】:

非常感谢您的回答,以及如何捕获 Ctrl+Alt +key、Ctrl+Shift+key、Alt+Key、Alt+Shift+key @Tigran84。我更新了我的答案。行编辑将只接受包含MOD_MASK 中的修饰符的组合键。 对不起,我从来没有见过这种赋值 MOD_MASK = (Qt.CTRL | Qt.ALT | Qt.SHIFT | Qt.META) 在那里我可以读到这个 @Tigran84。这只是一组被 OR'd 在一起的标志(括号不做任何事情)。 对不起,我的英语水平很规律,我不明白这个网站是如何运作的【参考方案2】:

当我们使用 key() 方法返回键的 int 值时是可能的,然后我们只需使用 unichr() 函数将 int 转换为 char

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)

【讨论】:

以上是关于在pyqt中按下Ctrl + anyKey时如何在QLineEdit中打印“Ctrl + key”的主要内容,如果未能解决你的问题,请参考以下文章

如何检测在 PyQt5 中按下了动态添加的按钮之一? [复制]

在 QtWidgets 的 PyQt5 中按下角落的红色 x 按钮时如何处理/覆盖?

如何在pyqt中按名称查找对象?

如何保存迭代编号。在matlab中按下按键

C#:如何在文本框中按下回车键触发按钮,但仍然允许“Ctrl+A”等快捷键通过?

C#:如何在文本框中按下输入触发按钮,但仍允许“Ctrl + A”等快捷方式通过?