View Full Version : Life time of a QMenu?

24th September 2015, 14:13

I have a question about the life time of QMenu. I use it as a custom context menu. It is declared on MainWindow class level (this->contextMenu) and is intended to be cleared and reused with different QActions depending on the column that is right-clicked in a QTableView. Here is my code:

void MainWindow::on_tableView_customContextMenuRequeste d(const QPoint &pos)
//Some code to add QActions depending on the column under pos
//In a first approach the context menu is placed 10px right of the mouse click position
QPoint kPos = ui->tableView->viewport()->mapToGlobal(pos) + QPoint(10, 0);
if (this->contextMenu->isVisible()) {
} else {

This code sort of works. If I right-click, the context menu opens. If I select a QAction from the menu, the menu is closed and the QAction is executed. However, if I don't select a QAction, but right-click on another cell, I want the context menu to be moved to the new position with a new set of QActions. My approach is to clear the QMenu, build it up from scratch and move it to the new position.
The problem is: Sometimes it works and sometimes it doesn't (I feel it depends on if I move the mouse between button down and button up). If it doesn't work, the menu is hidden instead. If I close the main window in this situation (hidden context menu), the main window won't close. The first close attempt seems to close the invisible context menu, the second attempt finally closes the main window.

Is the intended feature maybe to close the QMenu if popup() is called and it is already open?
What is the intended life time of a QMenu:
If I select a QAction, is it intended to be destroyed? Or hidden?
What is the best practice approach to reuse a QMenu?

What am I doing wrong?

24th September 2015, 15:22
void MainWindow::on_tableView_customContextMenuRequeste d(const QPoint &pos)
QMenu l_menu;
//.....get the data depend on cell & create actions add them to l_menu
// l_menu.addAction(action);

QPoint kPos = ui->tableView->viewport()->mapToGlobal(pos) + QPoint(10, 0); //check if your position is correct or not
menu.exec(kPos); // or else menu.exec(QCursor::pos());

Now menu is local & will be cleaned automatically, No memory leak.
No need to check if menu is visible or not.

24th September 2015, 18:00
Instead of recreating the menu(s) all the time, have you considered just hiding the action that are currently not applicable?