Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to specify mnemonics (ampersand shortcut) to QActions in a QMenu?

I'm using QActions in a QMenu, the typical

| &New file     Ctrl+N |
| &Open file    Ctrl+O |

Which gets a nice context shortcut of simply N (for New File) and O (for Open File) while the menu is open.

I'd like to do something similar for listing recent files, i.e.:

| [A recent file]          Ctrl+1  |
| [Another recent file]    Ctrl+2  |
 ... etc

It would be nice to set the mnemonic/context shortcut to the respective 1, and 2, without having to include this number in the text field:

| &1. [A recent file]          Ctrl+1  |
| &2. [Another recent file]    Ctrl+2  |

If anyone knows how to do this, or can point me in the direction of finding out, I'd be happy. I've looked through some of the documentation, and I can't find much mention of using the ampersand and equivalent ways of setting the mnemonic shortcut for QActions.

Thanks.

Ps: Qt-4.7.4-rh6-x86_64, C++

like image 250
swalog Avatar asked Oct 08 '22 20:10

swalog


2 Answers

You can create a shortcut valid only in the context of the menu:

QAction * recentFileAction = new QAction( tr("A recent file"), this );
recentFileAction->setShortcut( QKeySequence( tr("Ctrl+1") ) );

QMenu * tools = menuBar()->addMenu( tr("&Tools") );

// Add a shortcut valid only when the tools menu has focus
QShortcut * recentFileShortcut = new QShortcut( QKeySequence( tr("1") ), tools );
recentFileShortcut->setContext( Qt::WidgetShortcut );

connect( recentFileShortcut, SIGNAL(activated()),
         recentFileAction,   SLOT(trigger()));

You might need to set the menu's focus policy to Qt::StrongFocus so that it accepts keyboard inputs.

like image 167
Luc Touraille Avatar answered Oct 11 '22 08:10

Luc Touraille


Post-Notes:

  • Tested and confirmed working on linux / windows, using Qt-4.6.3-rh5-x86_64 and Qt-4.6.4-win32 respectively.
  • Tested and reported not working on Mac OS X by Kamil Klimek.

I'm not entirely sure if this is part of Qt intended functionality, or simply a hack. That I can't find any documentation, alludes to the latter, but that it works so nicely suggests the former. You be the judge, and let me/us know.

The usual usage was:

// Existing: QMenu* fileMenu_
QAction* action = new QAction("Recent file name", fileMenu_)
action->setShortcut(QKeySequence(QString("CTRL+").append(QString::number(1))));
fileMenu_->addAction(action);

Now, apparently, Qt populates the file menu as a table with two columns. The default behavior is having the label (name), on the left column, and the formatted shortcut keys on the right column.

| Recent file name      Ctrl+1 |

This can be customized easily by use of a an escaped tab. Such that using:

QAction* action = new QAction("Some text\tOther text", fileMenu_)
action->setShortcut(QKeySequence(QString("CTRL+").append(QString::number(1))));

Results in

| Some text       Other text |

While still retaining the default Ctrl+1 shortcut when out of focus. This leads to the solution:

QAction* action = new QAction(QString("Recent file name\tCtrl+&%1").arg(i)), fileMenu_)
action->setShortcut(QKeySequence(QString("CTRL+").append(QString::number(i))));

Where the variable i denotes the index of the recent file. This creates exactly what I had in mind, and also shows a underscore under the number, which indicates the mnemonic shortcut nicely.

Update

Just to demonstrate the end result, I've added some images in case there is any confusion.

Allowing Qt to populate the right column with the shortcut (what I had before asking the question, pretty standard):

After manually populating the right column, and also adding the mnemonic:

Which to me look identical, aside from the underline denoting the mnemonic.

like image 38
swalog Avatar answered Oct 11 '22 08:10

swalog