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?
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; });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With