PDA

View Full Version : Dynamic menu



folibis
25th November 2011, 00:49
I have TreeView with context menu (QMenu) in my program. But it have to be dynamic one, I mean than menu items created in runtime. Each item have his own set of actions.
My problem is how to avoid memory leaks.

I will illustrate it by example:


//menu initialization:
treeMenu = new QMenu(ui->objectTree);
connect(ui->objectTree,SIGNAL(customContextMenuRequested(const QPoint&)),this,SLOT(treePopupShow(const QPoint&)));

// slot
void MyProgram::treePopupShow(const QPoint & point) {
QModelIndex index = ui->objectTree->indexAt(point);
if(index.isValid())
{
TreeItem * item = static_cast<TreeItem *>(index.internalPointer());
if(item)
{
treeMenu->clear();
switch(item->getType())
{
case NodeType1:
QMenu * submenu1 = treeMenu->addMenu(tr("submenu1")); // memory leak
foreach(QString action,actionList1)
{
QAction * action = submenu1->addAction(action);
action->setData(action);
}
break;
case NodeType2:
QMenu * submenu2 = treeMenu->addMenu(tr("submenu2")); // memory leak
foreach(QString action,actionList2)
{
QAction * action = submenu2->addAction(action);
action->setData(action);
}
break;
}
}
}

It will be tens of such submenus like submenu1 and submenu2. and tens of top items. treeMenu->clear() clears only actions, not submenus. May be I have to store all of them to delete every time when menu is shown?

Spitfire
25th November 2011, 10:58
In this case there's no leak.
When calling clear() actions get removed and deleted (if not used anywhere else), menus don't but:
They don't leak as they're still parented ( clear() doesn't remove children ) so they will get deleted when the parent eventually gets destroyed.

You can test it by checking for parent on a menu that was just cleared.

Also to delete them you don't have to store them, you can get all the children by calling children() and then deleting them in a loop.

Edit: it does not apply when using QMenu::addMenu ( QMenu * menu ) as this method doesn't take ownership of the added menu.