Qt&将一个QMenu添加到另一个QMenu

时间:2016-02-25 02:56:15

标签: c++ qt qmenu

使用Qt5,假设我有一个控件实现自己的上下文菜单。并且假设在某些情况下我想某些项目添加到标准上下文菜单中。所以,要做到这一点,我创建一个临时QMenu,添加一些东西,并附加标准菜单。类似的东西:

// MyControl is derived from QPlainTextEdit
void MyControl::showContextMenu(const QPoint& pos)
{
    // This is QPlainTextEdit::createStandardContextMenu()
    QMenu* contextMenu = createStandardContextMenu();

    if (someCondition)
    {
        QMenu* tempMenu = new QMenu(this);
        /* add several actions to tempMenu */

        tempMenu->addSeperator();

        for (auto a : contextMenu->actions)
        {
            tempMenu->addAction(a);
        }

        // Feel like I should delete the original QMenu here but doing this
        // will delete the QActions it created
        // delete contextMenu; 
        contextMenu = tempMenu;
    }

    contextMenu->exec(mapToGlobal(pos));
    delete contextMenu;
}

我的问题是,这不会导致内存泄漏吗?如果是这样,那么正确的方法是什么?在delete contextMenu之前我无法contextMenu = newMenu;,因为这显然会删除我想要的操作。

编辑:

最终我要做的是使用createStandardContextMenu()返回分配的QMenu,然后将一些QActions添加到菜单的顶部,并确保没有任何泄漏。

3 个答案:

答案 0 :(得分:1)

QWidget::addAction(QAction*)不对该操作拥有所有权。删除contextMenu是否会导致删除操作取决于createStandardContextMenu的实施方式(例如QMenu::addAction(QString)确实对其创建的操作拥有所有权)。

因此,原始菜单所拥有的操作应该重新设置为父级:

for (auto a : contextMenu->actions)
    {
        tempMenu->addAction(a);
        if (a->parent() == contextMenu){
            a->setParent(tempMenu);
        }
    }
delete contextMenu;
contextMenu = tempMenu;

答案 1 :(得分:1)

insertAction上使用QMenu在第一个标准操作之前插入自定义操作,如下所示:

QMenu* contextMenu = createStandardContextMenu();
QAction* first = contextMenu->actions().at(0);
QAction* customAction = /* Create some custom action */
contextMenu->insertAction(first, customAction);

编辑:然后,您可以使用insertSeparator将自定义操作与第一个标准操作分开。

答案 2 :(得分:-1)

上下文菜单应该是模态对话框,所以不要使用动态分配,并传递"这个" to contructor,并根据传递的上下文构建菜单

(condition)
{
     context.add(...);
}

CustomMenu menu(this,context);
menu.exec(mapToGlobal(point));

没有代表添加评论,所以

 QMenu* tempMenu = new QMenu(this); 

不,这不会泄漏,因为你传递了父对象的指针。