Wednesday, June 10, 2009

Code to get a menu item in Qt

There is no easy way to get a menu item in Qt, since its menu structure is something like:
QMenuBar->QAction->QMenu->QAction... So I wrote a piece of code to retrieve certain menu item with its label.

Suppose there's a menu structure [Tools|QA Tools|Memory Monitor], the usage will be something like this (notice that the "&" is required if you have shortcuts defined) :
QStringList path;
path << "&Tools" << "&QA Tools" << "&Memory Monitor"; searchMenuItem(path);
The real code is here:




QAction* MainWindow::searchMenuItem(QAction* submenu, QStringList& path, int layer)
{
QAction* target = NULL;

if(submenu->text() == path[layer]){
target = submenu;
if(path.count() > layer+1){
target = searchMenuItem(target, path, layer+1);
}
}else{
QMenu* menu = submenu->menu();
QList actions = menu->actions();
foreach(QAction* act, actions){
if(act->text() == path[layer]){
target = act;
if(path.count() > layer+1){ //need to go deep
target = searchMenuItem(act, path, layer+1);
}
break;
}else{
// "ignore action ";
}
}
}

return target;
}

QAction* MainWindow::searchMenuItem(QStringList path)
{
if(!path.count()){
return NULL;
}

QAction* target = NULL;

QMenuBar* menus = this->menuBar();
Q_ASSERT(menus);
if(menus){
QList actions = menus->actions();
int i=0;
int layer = 0;

QString mainMenuLabel = path[0];

foreach(QAction* act, actions){
if(act->text() == mainMenuLabel){ //found 1st level menu item
target = act;
if(path.count() > layer+1){ //need to go deep
target = searchMenuItem(act, path, layer+1);
}
break;
}else{
// "ignore action ";
}
}
}
return target;
}