当其中一个QAction被触发时,防止QMenu关闭

gre*_*eth 14 c++ qt qt4

我正在使用QMenu作为上下文菜单.此菜单包含QActions.其中一个QAction是可检查的,我希望能够在不关闭上下文菜单的情况下检查/取消选中它(并且必须再次重新打开它以选择我想要的选项).

我已经尝试断开可检查QAction发出的信号而没有运气.

有任何想法吗?谢谢.

bay*_*ith 17

使用QWidgetAction和QCheckBox进行"可检查操作",这不会导致菜单关闭.

QCheckBox *checkBox = new QCheckBox(menu);
QWidgetAction *checkableAction = new QWidgetAction(menu);
checkableAction->setDefaultWidget(checkBox);
menu->addAction(checkableAction);
Run Code Online (Sandbox Code Playgroud)

在某些样式中,这与可检查的操作看起来不完全相同.例如,对于Plastique样式,复选框需要缩进一点.


Jak*_*ben 7

似乎没有任何优雅的方法来阻止菜单关闭.但是,菜单仅在动作可以实际触发时关闭,即启用.因此,我找到的最优雅的解决方案是通过在触发操作时立即禁用该操作来欺骗菜单.

  1. 子类QMenu
  2. 重新实现相关的事件处理程序(如mouseReleaseEvent())
  3. 在事件处理程序中,禁用操作,然后调用基类的实现,然后再次启用操作,并手动触发它

这是重新实现的mouseReleaseEvent()的示例:

void mouseReleaseEvent(QMouseEvent *e)
{
    QAction *action = activeAction();
    if (action && action->isEnabled()) {
        action->setEnabled(false);
        QMenu::mouseReleaseEvent(e);
        action->setEnabled(true);
        action->trigger();
    }
    else
        QMenu::mouseReleaseEvent(e);
}
Run Code Online (Sandbox Code Playgroud)

为了使解决方案更加完美,应该在可能触发操作的所有事件处理程序中进行类似操作,例如keyPressEvent()等...

麻烦的是,要知道您的重新实现是否应该实际触发操作,或者甚至应该触发哪个操作并不总是很容易.最困难的可能是由助记符触发的动作:您需要自己在QMenu :: keyPressEvent()中重新实现复杂的算法.

  • 您也可以不调用`QMenu :: mouseReleaseEvent`而不是禁用和启用操作.在这种情况下,它就像一个魅力.覆盖`keyPressEvent`并为空格按钮添加行为也很好. (2认同)