作为解决方案之一,您可以安装 QEvent::ShortcutOverride 事件过滤器:
QEvent::ShortcutOverride。
对于 QEvent::ShortcutOverride,接收器需要显式地接受事件以触发覆盖操作。在按键事件上调用 ignore() 将其传播到父窗口小部件。该事件沿着父窗口小部件链向上传播,直到某个窗口小部件接受它或事件过滤器消耗它。
当某个窗口小部件尝试覆盖快捷键事件时,将调用该事件,例如一个简单的示例:
我有一个带有一个 lineEdit 和窗口菜单的新 Qt 应用程序,其中 Ctrl+V 快捷键(覆盖了 lineEdit 的粘贴快捷键)。
以下是它的工作方式:
1.创建过滤方法,如果覆盖快捷操作,则会忽略(返回 true)快捷键覆盖(在示例应用程序中使用了 MainWindow::eventFilter,但您可以使用任何所需或想要的过滤对象)。最好遵循 Qt 文档并使用上面提到的 accept()/ignore(),但是在我的应用程序中,即使没有它们,只返回 true/false 也能正常工作。
2.将 p.1 中的事件过滤器安装到应该忽略覆盖操作的窗口小部件上。
3.我在设计师中添加了具有 Ctrl+V 快捷键的菜单操作。在下面的代码中,您将看到“来自窗口快捷方式的问候!”-当尝试粘贴(Ctrl+V)而不是实际的 lineEdit 粘贴操作时,菜单操作结果。
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->lineEdit->installEventFilter(this);
}
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
if (event->type() == QEvent::ShortcutOverride) {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->modifiers().testFlag(Qt::ControlModifier) && keyEvent->key() == 'V') {
qDebug() << "Ignoring" << keyEvent->modifiers() << "+" << (char)keyEvent->key() << "for" << watched;
event->ignore();
return true;
}
}
return QMainWindow::eventFilter(watched, event);
}
void MainWindow::on_action1_triggered()
{
qDebug() << "Hello from window shortcut!";
}
示例调试输出:
忽略LineEdit(0x575b10,名称="lineEdit")的QFlags(ControlModifier)+ V
来自窗口快捷方式的问候!
注意:不幸的是,您需要为所有希望不手动覆盖快捷方式的小部件安装此类过滤器。
更新:简单地说,您正在忽略底层小部件快捷键事件并将其传播到父小部件。
以下是Ctrl-Z(触发编辑中的撤消)和Ctrl-V(在编辑中被忽略而不是粘贴,并触发菜单操作)的比较:
区块I-开头的事件对Ctrl-Z和忽略的Ctrl-V都是相同的:
- QLineEdit接收到QKeyEvent(ShortcutOverride, Key_Control,ControlModifier)
- QLineEdit接收到QKeyEvent(KeyPress,Key_Control,ControlModifier)
- MainWindow接收到QKeyEvent(KeyPress,Key_Control,ControlModifier)
- QLineEdit接收到QKeyEvent(ShortcutOverride,Key_Z,ControlModifier)
区块II-差异发生的地方...
对于Ctrl-Z- lineEdit接收Ctrl + Z KeyPress事件,从而触发撤消操作:
QLineEdit接收到QKeyEvent(KeyPress,Key_Z,ControlModifier)
这里MainWindow不会收到任何事件,无论它是否具有Ctrl + Z操作快捷方式,它都被QLineEdit吞噬了。
对于Ctrl-V- MainWindow从QLineEdit传播Ctrl + V ShortcutOverride事件:
- 忽略QLineEdit代码中的"Ctrl+V"
- MainWindow接收到QKeyEvent(ShortcutOverride,Key_V,ControlModifier)
菜单操作触发的“来自窗口快捷方式的问候!”代码执行了槽函数。
在过滤器告诉QLineEdit忽略ShortcutOverride后,QLineEdit不会再接收到任何事件,而是执行MainWindow的快捷方式。
区块III-结尾的事件对Ctrl-Z和忽略的Ctrl-V也相同,只是按键释放事件:
- QLineEdit接收到QKeyEvent(KeyRelease,Key_Z,ControlModifier)
- MainWindow接收到QKeyEvent(KeyRelease,Key_Z,ControlModifier)
- QLineEdit接收到QKeyEvent(KeyRelease,Key_Control)
- MainWindow接收到QKeyEvent(KeyRelease,Key_Control)
P.S.我真的不知道为什么会发生这种情况-但这就是它的工作方式 :)
Qt::ApplicationShortcut
上下文中使用QShortcut
。或者我不理解你的逻辑和你想做什么。 - Dmitry SazonovqApp
而不是某个小部件吗? - king_nak