I built an application that uses QMenu
and its related submenu. The Qmenu
is triggered to open via QAction
.
The problem I have is that as soon as I call the QAction
and I chose the QAction
that carries the "Options", it should open the QMenu
, but instead the QMenu
open in another location of the application looking totally detached.
Below is the wrong behavior, where it is possible to see the QMenu
opening in another location of the Desktop.
Here is the expected behavior where the QMenu
opens up after selecting "Oprions":
I am not sure of why this is happening. Below the snippet of code related:
rostreewidget.h
class ROSTreeWidget : public QTreeWidget
{
Q_OBJECT
public:
enum ROSType {
NULLPTR,
TABLE,
BASE,
MENU
};
ROSTreeWidget(QWidget *parent = nullptr);
ROSType rostype(ROSTreeItem *rosItem) const;
ROSType rostype() const {
return rostype(currentItem());
}
signals:
void selectFrom();
void editLaserTable();
private:
QAction *mActionSELECT_FROM;
QAction *mActionEditLaserTable;
QAction *mAddMenuOptions;
QMenu *submenuLaserScanA;
QAction *submenuActionA, *submenuActionB, *submenuActionC;
QMenu *submenuLaserScanB;
QAction *submenuActionAA, *submenuActionBB, *submenuActionCC;
QMenu *submenuLaserScanC;
QAction *submenuActionAAA, *submenuActionBBB, *submenuActionCCC;
};
rostreewidget.cpp
ROSTreeWidget::ROSTreeWidget(QWidget *parent) : QTreeWidget(parent)
{
mActionSELECT_FROM = new QAction(QIcon(":"), "SELECT * FROM", this);
mActionEditLaserTable = new QAction(QIcon(":"), "Edit LaserScan Table");
mAddMenuOptions = new QAction(QIcon(":"), "Options", this);
addActions({ mActionSELECT_FROM,
mActionEditLaserTable,
mAddMenuOptions});
connect(mActionSELECT_FROM, &QAction::triggered, [&]() {
emit selectFrom();
});
connect(mActionEditLaserTable, &QAction::triggered, [&]() {
emit editLaserTable();
});
connect(mAddMenuOptions, &QAction::triggered, [&]() {
mMenu = new QMenu();
submenuLaserScanA = mMenu->addMenu( "Menu A" );
mMenu->addSeparator();
submenuLaserScanB = mMenu->addMenu( "Menu B" );
mMenu->addSeparator();
submenuLaserScanC = mMenu->addMenu( "Menu C" );
submenuActionAAA = submenuLaserScanC->addAction("Setup C" );
submenuActionBBB = submenuLaserScanC->addAction( "Setup C" );
mMenu->show();
});
}
What I have done so far:
After following this source I was able to prepare the menu and the submenu to be inserted in the QAction
and in fact all the related settings about it are as I need them to be.
I thought that linking the QAction
inside the lambda function, exactly as I did for the other choices, would have worked, but instead what I am obtaining as soon as I launch the application is a QMenu
that opens in another location of the Desktop without being linked to the main choice as shown below.
According to the documentation QMenu::addMenu parameters set are correct, so what is going on?
Thanks for pointing to the right direction for solving this issue.
Use this as a general pattern:
{
QMenu menu;
menu.addAction(...);
menu.addAction(...);
menu.exec(QCursor::pos()); // exec returns a triggered QAction
// process action
}
QMenu::exec()
is modal. You don't need a QMenu instance outside the function.