QWidgetAction调用setVisible()仅变灰未隐藏,是否为Qt-5.9 bug?
解决Qt5.9中QWidgetAction调用setVisible()无法正确隐藏的问题
我之前也碰到过类似的困扰,在Qt5.9里操作QWidgetAction的可见性时,直接调用setVisible(false)确实会出现你描述的情况:动作没真正隐藏,只是呈现禁用状态还被其他动作覆盖。这大概率是用法上的问题,而非单纯的Qt版本bug,下面给你拆解原因和解决办法:
问题根源
QWidgetAction和普通QAction的逻辑不一样,它内部包含一个自定义widget,直接调用action的setVisible()只会标记动作的可见状态,但不会同步处理内嵌widget的显示/隐藏,也不会触发菜单重新布局,导致视觉上出现异常。
正确的处理方式
你需要同步控制QWidgetAction的内嵌widget的可见性,同时触发菜单刷新布局,具体步骤如下:
- 获取QWidgetAction对应的widget:通过
QWidgetAction::defaultWidget()或者你自己创建widget时的引用拿到目标控件。 - 设置widget的可见性:调用widget的
setVisible(false),这才会真正隐藏内嵌的控件。 - 触发菜单重新布局:调用菜单的
updateGeometry()或者update()方法,让菜单重新计算布局,避免出现覆盖问题。
代码示例(修改你的测试脚本)
假设你的测试代码里有类似这样的片段:
QWidgetAction *action1 = new QWidgetAction(menu); QPushButton *btn = new QPushButton("Test Widget Action"); action1->setDefaultWidget(btn); menu->addAction(action1); // 原来的错误写法 // action1->setVisible(false); // 正确写法 btn->setVisible(false); action1->setVisible(false); // 同步标记action的状态 menu->updateGeometry(); // 强制菜单重新布局
额外注意事项
- 如果你的QWidgetAction是动态创建的,记得在隐藏时也要确保action的
visible属性和widget的状态一致,避免后续菜单更新时出现状态不一致的问题。 - Qt5.9作为比较老的版本,确实存在一些小bug,但这个场景下优先检查用法,大部分情况都是因为没有同步处理widget和action的状态导致的。
内容的提问来源于stack exchange,提问作者Trap
相关产品推荐
相关产品推荐

