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)
我理解 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)