Since you don't know in advance what the menu items will be, then you can't define a unique slot that will get executed when the item is triggered.
In that case, I would make a new QAction instance for every item in the menu, and use the QAction::setData() method to store some kind of value that uniquely identifies each item in the menu tree. Connect all of the QMenu::triggered() signals to the same slot, and in the slot use the QAction pointer and the data value so you can identify which menu item was invoked.
You need to build the menu recursively (this is pseudo-code):
void MyWindow
::buildProductMenu( QMenu * parentMenu, MyProductTreeItem
* parentItem
) {
action->setCheckable( true );
action->setChecked( false );
action->setData( parentItem->productCode() ); // Some unique identifier
parentMenu->addAction( action );
connect( parentMenu,
SIGNAL( triggered
( QAction * ) ),
this,
SLOT( productMenuActionTriggered
( QAction * ) ) );
if ( parentItem->hasChildren() ) // create sub menus for each child
{
// pseudocode
for each child Item in parentItem
{
QMenu * childMenu
= parentMenu
->addMenu
( childItem
->productName
() );
buildProductMenu( childMenu, childItem );
}
}
}
void MyWindow
::productMenuActionTriggered( QAction * action
) {
// Convert QVariant to whatever it should really be, then use that to look up whatever
// product it refers to. Do something appropriate once you know.
}
void MyWindow::buildProductMenu( QMenu * parentMenu, MyProductTreeItem * parentItem )
{
QAction * action = new QAction( parentItem->productName(), this );
action->setCheckable( true );
action->setChecked( false );
action->setData( parentItem->productCode() ); // Some unique identifier
parentMenu->addAction( action );
connect( parentMenu, SIGNAL( triggered( QAction * ) ), this, SLOT( productMenuActionTriggered( QAction * ) ) );
if ( parentItem->hasChildren() ) // create sub menus for each child
{
// pseudocode
for each child Item in parentItem
{
QMenu * childMenu = parentMenu->addMenu( childItem->productName() );
buildProductMenu( childMenu, childItem );
}
}
}
void MyWindow::productMenuActionTriggered( QAction * action )
{
QVariant productID = action->data();
// Convert QVariant to whatever it should really be, then use that to look up whatever
// product it refers to. Do something appropriate once you know.
}
To copy to clipboard, switch view to plain text mode
Something like that; you'll need to try this and fix whatever I didn't get right.
At the topmost level, you call buildProductMenu() with the QMenu pointer corresponding to "Products" and the pointer to the root item in your Products data tree.
If your product menu changes during the course of executing the program (that is, the product tree itself is dynamic), then you would need to destroy and rebuild the product menu tree whenever the product tree changes.
Bookmarks