使用 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;
之前,我无法delete contextMenu
,因为这显然会删除我想要的操作。
编辑:
最终我想做的是使用 createStandardContextMenu()
返回分配的 QMenu,然后在菜单顶部添加一些 QActions,并确保没有任何泄漏。
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
将自定义操作与第一个标准操作分开。
上下文菜单应该是模式对话框,所以不要使用动态分配,并将"this"传递给构造器,并根据传递的上下文构建菜单
(condition)
{
context.add(...);
}
CustomMenu menu(this,context);
menu.exec(mapToGlobal(point));
没有代表添加评论,所以
QMenu* tempMenu = new QMenu(this);
不,这不会泄漏,因为您传递父对象的指针。