Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Qt&;将一个QMenu前置到另一个QMenu_C++_Qt_Qmenu - Fatal编程技术网

C++ Qt&;将一个QMenu前置到另一个QMenu

C++ Qt&;将一个QMenu前置到另一个QMenu,c++,qt,qmenu,C++,Qt,Qmenu,使用Qt5,假设我有一个控件实现它自己的上下文菜单。假设在某些情况下,我想在标准上下文菜单中添加一些项目。因此,要做到这一点,我创建了一个临时的QMenu,向其中添加了一些内容,然后添加标准菜单。比如: // MyControl is derived from QPlainTextEdit void MyControl::showContextMenu(const QPoint& pos) { // This is QPlainTextEdit::createStandardCo

使用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;
}
我的问题是,这不是在引入内存泄漏吗?如果是的话,正确的方法是什么?在执行
contextMenu=newMenu之前,我不能
删除contextMenu
编辑:


最后,我想做的是使用
createStandardContextMenu()
,它返回一个分配的QMenu,然后在菜单的顶部添加一些qAction,并确保没有泄漏。

上下文菜单应该是模态对话框,所以不要使用动态分配,并将“this”传递给constructor,并根据传递的上下文生成菜单

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

CustomMenu menu(this,context);
menu.exec(mapToGlobal(point));
没有代表添加评论,因此

 QMenu* tempMenu = new QMenu(this); 

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

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;

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

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

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

好像newMenu和tempMenu是一样的?但是代码是不正确的。是的,如果没有修复的话,这里会有很多漏洞。现在看起来contextMenu也在泄漏。不知道你为什么这么做。是的,他们是一样的。很抱歉,我已经修好了。@Addy,为了避免内存泄漏,您可以用它代替普通的pointer@VladimirBershov我甚至没有想到这一点,但这是一个伟大而简单的想法。谢谢大家!@VladimirBershov您的建议并不真正适用于小部件,只要它们可以让父级负责对象销毁。我不会在小部件中使用共享指针。我不相信这个答案为我提供了一个解决方案,可以有条件地将项目预先添加到已经存在的
QMenu
,而不会出现泄漏。另外,
createStandardContextMenu()
返回一个动态分配的
QMenu
,我别无选择,只能使用它。将上下文传递给createStandardContextMenu(),将构造函数添加到处理数据的CustomMenu,否则将CustomMenu重命名为DummyMenu,因为它什么都不做。
createStandardContextMenu
是一个Qt函数,只能接受QPoint.setContextMenuPolicy(Qt::CustomContextMenu);连接(此,信号(customContextMenuRequested(const QPoint&)),此,插槽(onCustomContextMenu(const QPoint&));从QMenu创建子类的局部变量