PDA

View Full Version : Additional keyboard shortcut for a menu



negritot
14th September 2009, 23:55
The first item in my main menu is called "Project":



m_projectMenu = new QMenu("Pro&ject", m_menuBar);


So the user can hit "Alt+J" to open the menu via keyboard shortcut. Great!

For historical reasons, I'd also like the keyboard shortcut "Alt+F" to open the menu. I thought I could use a QShortcut, and hook it up to the menu's action:



QShortcut* fileshortcut = new QShortcut(QKeySequence("Alt+F"), m_projectMenu);
QObject::connect(fileshortcut, SIGNAL(activated()),
m_projectMenu->menuAction(), SLOT(trigger()));


But then pressing "Alt+F" only acts as if the mouse is hovering over the menu, rather than clicking to display the menu.

Then I thought of adding multiple keyboard shortcuts to the menu:



QList<QKeySequence> shortcuts;
shortcuts.push_back(QKeySequence("Alt+F"));
shortcuts.push_back(QKeySequence("Alt+J"));

m_projectMenu->menuAction()->setShortcuts(shortcuts);


But that doesn't work either. "Alt+F" does nothing, and "Alt+J" results in messages in stdout/stderr:

QAction::eventFilter: Ambiguous shortcut overload: Alt+J

So what's the correct way to do this? It seems that menuAction() does not return what I thought it returned, but the docs only say "Returns the action associated with this menu." Is that not the action on which keyboard shortcuts should be installed?

yogeshgokul
15th September 2009, 06:14
You can do this like :


QShortcut* fileshortcut = new QShortcut(QKeySequence("Alt+F"), this);
QObject::connect(fileshortcut,SIGNAL(activated()), this,SLOT(customSlot()));

void customSlot()
{m_projectMenu->exec();}

negritot
15th September 2009, 18:25
Thank you! That gets me one step of the way.

The next step is to display the menu in the correct location (using exec with no parameters shows the menu at location 0,0 in global screen coordinates). The documentation suggests that I can display the menu aligned with a specific widget by getting the widget's global coordinates using QWidget::mapToGlobal:



void UIControl::openProjectMenu()
{
QPoint menuPos = m_projectMenu->mapToGlobal(QPoint(0,0));
m_projectMenu->exec(menuPos);
}

However, that still displays the menu at location 0,0. I believe that I'm not using the correct widget in the mapToGlobal call, but I'm not sure what other widget to use. Any ideas?

yogeshgokul
16th September 2009, 07:23
Here is your solution. ;)


void UIControl::openProjectMenu()
{
QPoint p = menubar->mapToGlobal(menubar->pos());
p.setY(p.y() + menubar->height());
m_projectMenu->exec(p);
}

negritot
16th September 2009, 18:07
yogeshgokul, thanks so much for the solution!

I'm curious: what would you do if you needed to position the menu under the second menu entry in the menu bar?

yogeshgokul
17th September 2009, 06:58
I'm curious: what would you do if you needed to position the menu under the second menu entry in the menu bar?
I knew that you will arise this point. Ok !
So the solution is not straight forward for that. You can do it by playing with size of entries in menubar.
But I suggest you to do not waste time for this thing. Go straight and use default hot key for menus forget shortcuts for menu invoking.
Lets use shortcuts for QActions only. :)