当QWidgetAction被触发时,你如何关闭QMenu?

时间:2015-09-28 13:40:43

标签: c++ qt qmenu

我有一个QMenu我为其创建了一个QColorModel操作窗口小部件(它实际上只是一个QStandardItemModel)。我希望的行为是,当用户单击模型中的一种颜色时,操作应该触发,菜单关闭。但是,即使我手动触发操作,它也似乎无法做到这一点。

我已尝试手动隐藏菜单,但它是一个kludge,因为它不会隐藏菜单可能附加到的父菜单。

以下是相关的代码部分:

// color menu
m_colorMenu = new QMenu("color", this);
m_colorView = new QColorView(m_colorMenu);

m_colorViewAction = new QWidgetAction(m_colorMenu);
m_colorViewAction->setDefaultWidget(m_colorView);

m_colorView->setModel(new QStandardColorModel);
connect(m_colorView, &QColorView::clicked, [&](QModelIndex index)
{
    QColor color = qvariant_cast<QColor>(index.data(Qt::DecorationRole));
    if (m_pen.color() != color)
    {
        m_pen.setColor(color);
        drawIcon();
        drawColorIcon();
        update();
    }
    //this->hide();                // kludge, didn't close all parent menus
    m_colorViewAction->trigger();  // doesn't seem to cause menu closure

});

m_colorMenu->addAction(m_colorViewAction);

修改

我也试过添加一些效果:

QMenu* menu = m_colorMenu;
do
{
    menu->close();
    menu = dynamic_cast<QMenu*>(menu->parent());
} while (menu);

但它也是脆弱/ kludgey因为它假定a)所有小部件都是正确的父级,并且b)所有父母实际上应该是菜单。就我而言,他们不是。

1 个答案:

答案 0 :(得分:2)

如果包含的菜单不在父母树中,并且您要关闭的菜单不是顶级菜单,则没有简单的方法可以执行此操作。那说,有:

核选项

将其添加到lambda函数的末尾

auto topLevelWidgets = qApp->topLevelWidgets();
for (auto widget : topLevelWidgets)
{
    QMenu* menu = dynamic_cast<QMenu*>(widget);
    if (menu)
    {
        menu->close();
    }
}
一旦触发动作,

将导致所有顶级菜单关闭。这是完成你想要的相对好的方法,因为:

  1. 其中一个顶级菜单将包含相关菜单,
  2. 从不说永远不会,但是我不能想到你曾经(或想要)一次打开一个以上菜单的单个案例,所以很可能是你要关闭的唯一打开的菜单树是预期的之一。