【问题标题】:Ctrl+Alt key modifier behavior with Qt on windows when a textbox has focus当文本框具有焦点时,Windows 上 Qt 的 Ctrl+Alt 键修饰符行为
【发布时间】:2012-02-28 22:03:15
【问题描述】:

我做了一个快速的示例程序来演示这个问题

import sys

from  PyQt4 import QtGui
from PyQt4.QtCore import Qt

class AWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(AWindow, self).__init__(parent=parent)

        self.setCentralWidget(QtGui.QWidget())
        self.centralWidget().setLayout(QtGui.QFormLayout())

        self.centralWidget().layout().addRow(
            QtGui.QLabel('some text'),
            QtGui.QLineEdit()
            )
        self.centralWidget().layout().addRow(
            QtGui.QLabel('some text'),
            QtGui.QCheckBox('this is checkbox')            
            )

    def keyPressEvent(self, e):
        if int(e.modifiers()) == (Qt.ControlModifier+Qt.AltModifier):
            if e.key() == Qt.Key_K:
                #when ctrl+alt+k is pressed, a message box should open
                msg = QtGui.QMessageBox(
                    QtGui.QMessageBox.Information,
                    'w00t',
                    'You pressed ctrl+alt+k'
                    )
            msg.exec_()
def main():
    app = QtGui.QApplication(sys.argv)
    w = AWindow()
    w.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

问题

在此示例中,我正在捕获 ctrl+alt+k 键盘快捷键。问题是,如果文本输入小部件在按下这些键时具有键盘焦点,则 keyPressEevent 处理程序不会捕获它,而是在框中键入大写字母 K。 (这与所有 ctrl+alt 按键相同)。

如果另一种小部件获得焦点,即不接受文本输入的小部件(例如复选框、按钮),则按键将按应有的方式注册,并且在示例中,将显示消息框。
此外,仅使用 Ctrl 修饰符的键盘快捷键也可以正常工作。

这个问题只出现在 Windows 上,而不是在 Linux 上,所以这让我相信这与 windows 如何处理 ctrl+alt 修饰符有关,或者我可能没有正确捕获修饰符。

有没有办法解决这个问题?

编辑

我从 Spidey 的评论中得出了这个解决方案。
我继承了 QLineEdit 并像这样处理它的 keyPressEvent 。

#EDIT: this doesn't work, see below
def keyPressEvent(self, e):
    if e.modifiers() and Qt.ControlModifier and Qt.AltModifier:
        e.ignore()
    super(CoolLineEdit, self).keyPressEvent(e)

再次编辑

将修饰符添加为整数并在 e.ignore() 之后返回(也许不需要忽略)似乎非常重要。
这是真正的解决方案。

def keyPressEvent(self, e):
    if int(e.modifiers()) == (QtCore.Qt.ControlModifier+QtCore.Qt.AltModifier):
        e.ignore()
        return
    super(SaveLineEdit, self).keyPressEvent(e)            

【问题讨论】:

  • 我不确定,但 AFAIK 事件是从小部件树的底部处理的,因此 QLineEdit 小部件在 QMainWindow 之前捕获它是很自然的。
  • 是的。就是这样。我尝试将 lineedit 子类化并在那里捕获 keyPressEvent ,我想我可能已经解决了(参见 OP 中的编辑)。仍然奇怪的是,在 Windows 上 ctrl+alt 的处理方式就像 shift 一样,现在当我在寻找时,我在其他 Qt 应用程序中也注意到了它。
  • 很高兴看到您提出了这个建议 - 见下文,在您发表评论前一分钟 :)

标签: python windows qt pyqt


【解决方案1】:

QLineEdit,当它有焦点时,正在处理`QKeyEvent。如果您在 Windows 上需要此功能,我建议:

1) 从QLineEdit 派生一个类(或任何你想要的QTextEdit 派生类)。

2) 覆盖 virtual void keyPressEvent(QKeyEvent* e) 并检查您的特定组合键。

3) 如果你找到它,不处理就返回,它会掉到下一层(你的窗口,它会捕捉到它并打印你的消息)。

4) 如果找不到,显式调用函数的基类版本:BaseClass::keyPressEvent(e);,以便正确处理正常的按键操作。

对不起 c++ 语法,我没有使用 PyQt。

【讨论】:

  • Grat minds think alike :) 我很好奇qt默认如何处理ctrl+alt修饰符的原因,也许我会提交一个错误报告。
  • 是的,我也觉得很奇怪。我没有注意到其他应用程序中的这种行为。
猜你喜欢
  • 2018-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多