Qt ShortcutOverride 默认操作

Qt ShortcutOverride default action

我理解 QEvent::ShortcutOverride 发生在父项中注册了快捷方式并且子项想要 "go against the rule" 时。 Qt Wiki 上给出的示例是一个媒体播放器,它使用 Space 暂停,但 QLineEdit 可能想要使用 Space,这很有意义。

此外,如果事件被接受,则会为子窗口小部件生成一个 QEvent::KeyPress,以便您可以处理您的特殊情况。

现在,我的问题是,为什么在使用标准快捷方式时默认操作似乎是 接受 QEvent::ShortcutOverride?在我看来,这与名称所暗示的相反,即默认情况下会覆盖它,您必须处理事件才能让快捷方式通过。

在下面的代码中,如果您不安装事件过滤器,您将看不到消息。

from PySide.QtGui import QApplication
from PySide import QtGui, QtCore

app = QApplication([])

class Test(QtGui.QWidget):
    def __init__(self, parent=None):
        super(Test, self).__init__(parent)

        self.setLayout(QtGui.QVBoxLayout())
        self.w_edit = QtGui.QLineEdit(parent=self)
        self.layout().addWidget(self.w_edit)

        # If we install the event filter and ignore() the ShortcutOverride
        # then the shortcut works
        self.w_edit.installEventFilter(self)

        # Ctrl+Left is already in use (jump to previous word)
        shortcut = QtGui.QShortcut(QtGui.QKeySequence('Ctrl+Left'), self)
        shortcut.setContext(QtCore.Qt.ApplicationShortcut)
        shortcut.activated.connect(self.test_slot)

    def test_slot(self):
        print('ctrl+left pressed!')

    def eventFilter(self, obj, event):
        if obj is self.w_edit and event.type() == QtCore.QEvent.ShortcutOverride:
            # Send the event up the hierarchy
            event.ignore()
            # Stop obj from treating the event itself
            return True

        # Events which don't concern us get forwarded
        return super(Test, self).eventFilter(obj, event)

widget = Test()
widget.show()

if __name__ == '__main__':
    app.exec_()

我的实际情况是一个选项卡小部件,我想使用 Ctrl+Left/Right 循环浏览选项卡,除非 QLineEdit 之类的东西具有焦点,否则它会起作用。我觉得除了在所有 QLineEdit 和任何其他可以使用组合键的小部件上调用 event->ignore(); return true 之外应该有更好的方法,我在这里遗漏了什么吗?

谢谢!

您可以在应用程序实例上设置一个事件过滤器,然后进行相应的过滤:

        QtGui.qApp.installEventFilter(self)
        # self.w_edit.installEventFilter(self)
        ...

    def eventFilter(self, source, event):
        if event.type() == QtCore.QEvent.ShortcutOverride:
            # filter by source object, source.parent(), or whatever...
            if isinstance(source, QtGui.QLineEdit):
                event.ignore()
                return True
        return super(Test, self).eventFilter(source, event)