Qt隐藏菜单项

一. 缺陷信息

  缺陷:当QMenu使用QMenu::addMenu(QMenu *menu)添加一个子菜单后。想隐藏子菜单时,调用hide()或者setVisible()时,子菜单依然会显示

二.根因分析

  Qt在加入子菜单的时候,在菜单中只加了子菜单的action

QAction *QMenu::addMenu(QMenu *menu)
{
    QAction *action = menu->menuAction();
    addAction(action);
    return action;
}
​
void QWidget::addAction(QAction *action)
{
    insertAction(nullptr, action);
}
​
void QWidget::insertAction(QAction *before, QAction *action)
{
    if (Q_UNLIKELY(!action)) {
        qWarning("QWidget::insertAction: Attempt to insert null action");
        return;
    }
​
    Q_D(QWidget);
    if (d->actions.contains(action))
        removeAction(action);
​
    int pos = d->actions.indexOf(before);
    if (pos < 0) {
        before = nullptr;
        pos = d->actions.size();
    }
    d->actions.insert(pos, action);
​
    QActionPrivate *apriv = action->d_func();
    apriv->associatedObjects.append(this);
​
    QActionEvent e(QEvent::ActionAdded, action, before);
    QCoreApplication::sendEvent(this, &e);
}

 并且在QMenu的hideEvent中并没有进行隐藏action的操作 

void QMenu::hideEvent(QHideEvent *)
{
    Q_D(QMenu);
    emit aboutToHide();
    if (d->eventLoop)
        d->eventLoop->exit();
    d->setCurrentAction(nullptr);
#ifndef QT_NO_ACCESSIBILITY
    QAccessibleEvent event(this, QAccessible::PopupMenuEnd);
    QAccessible::updateAccessibility(&event);
#endif
#if QT_CONFIG(menubar)
    if (QMenuBar *mb = qobject_cast<QMenuBar*>(d->causedPopup.widget))
        mb->d_func()->setCurrentAction(nullptr);
#endif
    if (QMenuPrivate::mouseDown == this)
        QMenuPrivate::mouseDown = nullptr;
    d->hasHadMouse = false;
    if (d->activeMenu)
        d->hideMenu(d->activeMenu);
    d->causedPopup.widget = nullptr;
    d->causedPopup.action = nullptr;
    if (d->scroll)
        d->scroll->scrollTimer.stop(); //make sure the timer stops
}

 所以我们调用QMenu的hide()或者setVisible()是没有用的

三.修复方案

 隐藏时需要调用子菜单的QMenu::menuAction()->setVisible(false);

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值