Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When and how to properly destroy QMenu context menu?

Tags:

c++

qt

qmenu

I allow custom context menu to appear over a table. This is how the menu is generated, using a generic function that accepts target widget and coordinates:

#include <QMenu>
void MainWindow::makeContextMenu(const QPoint& pos, QWidget* target)
{
    QMenu *menu = new QMenu(this);
    menu->addAction(new QAction("Action 1", menu));
    menu->addAction(new QAction("Action 2", menu));
    menu->addAction(new QAction("Action 3", menu));
    // Notify window about clicking
    QObject::connect(menu, &QMenu::triggered, this, &MainWindow::menuClicked);
    // If this is a scroll area, map coordinates to real app coordinates
    if(QAbstractScrollArea* area = dynamic_cast<QAbstractScrollArea*>(target))
        menu->popup(area->viewport()->mapToGlobal(pos));
    else
        menu->popup(pos);
}

The problem is that the QMenu* menu never gets destroyed and removed from memory. It persists as MainWindow's child even after it's hidden.

What should I do? Can I set the menu to delete itself? Or should I reuse the same instance of menu or maybe save it into same pointer?

like image 900
Tomáš Zato - Reinstate Monica Avatar asked Sep 12 '25 18:09

Tomáš Zato - Reinstate Monica


1 Answers

It doesn't have to be so complicated. That's it already:

menu->setAttribute(Qt::WA_DeleteOnClose);

That way when the QMenu is closed, the class is deleted as soon as the event loop is entered again. And it doesn't matter if an action was triggered or the popup was just closed.

To prove my answer, you can test it yourself by checking when the menu is created and if the 'deleted' message is triggered with the same address:

qDebug() << "created" << (qintptr)menu;
connect(menu, &QMenu::destroyed, 
        this, [menu]() { qDebug() << "deleted" << (qintptr)menu; });
like image 68
m.w. Avatar answered Sep 14 '25 10:09

m.w.