C++ Qt&;将一个QMenu前置到另一个QMenu
使用Qt5,假设我有一个控件实现它自己的上下文菜单。假设在某些情况下,我想在标准上下文菜单中添加一些项目。因此,要做到这一点,我创建了一个临时的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
// 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创建子类的局部变量