gpt4 book ai didi

Qt 覆盖小部件快捷方式(窗口快捷方式)

转载 作者:行者123 更新时间:2023-12-04 19:29:54 24 4
gpt4 key购买 nike

我有一个 Qt 应用程序,其中包含在 Qt 设计器表单操作中定义的多个窗口快捷方式。快捷方式运行良好,直到在焦点位于处理相同组合的小部件上时按下它们(覆盖我的窗口快捷方式)。

我想要相反的行为:窗口快捷方式覆盖焦点小部件快捷方式。

我尝试使用 eventFilter我可以捕获所需的事件,但我无法以调用全局快捷方式的方式重新发送它们。我可以使用一个大开关并自己调用 Action ,但当然,我想避免这种情况。

我用过 postEventsendEventeventFilter使用 MainWindow作为接收者,但事件被忽略:

bool MainWindow::eventFilter(QObject*, QEvent* event) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Z
&& keyEvent->modifiers() == Qt::ControlModifier) {
//Calling the triggers directly works
ui->actionUndo->trigger();
return true;
} else if (keyEvent->modifiers().testFlag(
Qt::KeypadModifier)) {
QKeyEvent* ev2
= new QKeyEvent(keyEvent->type(), keyEvent->key(), 0);
qDebug() << keyEvent << ev2;
//This sendEvent doesn't work
QApplication::sendEvent(ui->widget, ev2);
event->accept();
return true;
} else {
return false;
}
}
return false;
}

最佳答案

作为解决方案之一,您可以安装 QEvent::ShortcutOverride事件过滤器:

For QEvent::ShortcutOverride the receiver needs to explicitly accept the event to trigger the override. Calling ignore() on a key event will propagate it to the parent widget. The event is propagated up the parent widget chain until a widget accepts it or an event filter consumes it.



当某些小部件尝试覆盖快捷方式事件时,将调用该事件,例如只是一个简单的例子:

我只有一个新的 Qt 应用程序,带有一个 lineEdit 和带有 Ctrl+V 快捷方式的窗口菜单(覆盖 lineEdit 中的粘贴快捷方式)。

这是它的工作原理:

1.创建将忽略(返回 true)快捷方式覆盖的过滤方法(我在示例应用程序中使用了 MainWindow::eventFilter,但是您可以使用任何您需要或想要的过滤对象)。最好遵循 Qt 文档并使用上面提到的 accept()/ignore(),但是在我的应用程序上它工作得很好,没有它们只是返回 true/false。

2.将事件过滤器从 p.1 安装到小部件,如果覆盖,则应忽略快捷操作。

3.我在设计器中添加了带有 Ctrl+V 快捷键的菜单操作。在下面的代码中,您会看到 "Hello from window shortcut!" - 菜单操作结果,当尝试粘贴 (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);
// Ignore only the Ctrl + V shortcut override, you can customize check for your needs
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!";
}

示例调试输出:

Ignoring QFlags(ControlModifier) + V for QLineEdit(0x575b10, name = "lineEdit")

Hello from window shortcut!



注意:不幸的是,您应该为所有不想手动覆盖快捷方式的小部件安装此类过滤器。

更新:很快 - 您将忽略底层小部件快捷方式事件并将其传播到父小部件。

下面是 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)

  • 第二块 - 差异发生的地方...

    对于 Ctrl-Z - lineEdit 接收到 Ctrl+Z KeyPress 事件,触发 Undo 操作:
  • QLineEdit 接收 QKeyEvent(KeyPress, Key_Z, ControlModifier)

    这里 MainWindow 没有收到任何事件,不取决于它是否有 Ctrl+Z 操作快捷方式,它只是被 QLineEdit
  • 吞噬了。

    对于 Ctrl-V - MainWindow 接收从 QLineEdit 传播的 Ctrl+V ShortcutOverride 事件:
  • filterEvent 中执行 QLineEdit 代码时忽略“Ctrl+V”
  • MainWindow 收到 QKeyEvent(ShortcutOverride, Key_V, ControlModifier)
  • “从窗口快捷方式你好!”来自菜单操作触发插槽的代码已执行。

    这里 QLineEdit 在过滤器告诉它忽略 ShortcutOverride 后没有收到任何事件,而是执行 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)

  • 附言我真的不知道为什么会这样 - 但这就是它的工作原理:)

    关于Qt 覆盖小部件快捷方式(窗口快捷方式),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44914888/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com