6

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++

swalog
  • 4,403
  • 3
  • 32
  • 60

2 Answers2

4

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.

Luc Touraille
  • 79,925
  • 15
  • 92
  • 137
  • Just courious, but did you test it on Mac OS X? I gues it will have some limitation especially about focus in/out on app menu – Kamil Klimek Feb 02 '12 at 13:24
  • I did not try this on Mac OS X, no, but the focus on menus seems a little odd on Windows XP too. Sadly, I don't have much time to investigate this behavior, so I'll let the OP give us some updates if he experiments with this approach. – Luc Touraille Feb 02 '12 at 13:41
  • I'll let you guys know in < 24 hours. And thanks Luc, it looks promising. – swalog Feb 02 '12 at 14:09
  • I didn't have any success with the method above. It might be that I've forgotten to do something important, or that some setting or flag has been set somewhere that hinders Luc's suggestion from working (I'm working with an existing codebase that I'm not 100% familiarized with yet). I did however stumble upon a solution of my own, which uses Qt's own inner workings, so I guess it should work fine on Mac OSX. I'll post my solution shortly. Again, thanks Luc. – swalog Feb 03 '12 at 14:08
1

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.

swalog
  • 4,403
  • 3
  • 32
  • 60
  • I'll wait a few days for criticism and other suggestions before accepting any answers. – swalog Feb 03 '12 at 14:29
  • CTRL+1 in your "recent list" will look completly different from "CTRL+X" added automaticly from QAction shortcut field. This solution doesn't look any different from &1. Filename.ext. You still add &1 and you wanted to avoid it. – Kamil Klimek Feb 04 '12 at 21:18
  • @Kamil Klimek: I'm not sure I get what you are saying. Your statement << "CTRL+1 in your "recent list" will look completly different from "CTRL+X" added automaticly from QAction shortcut field." >> is as far as I can tell false, or not valid for my platform / version of qt, etc. Could you please elaborate? Also, I never said I wanted to avoid &1, just not make it part of the left side text in the file menu. Please read what I wrote a bit more carefully, and let me know if it still unclear. – swalog Feb 06 '12 at 08:53
  • @Kamil Klimek: Take a look at the update. They don't seem completely different. – swalog Feb 06 '12 at 09:08
  • ok, now change Project (/tmp/...) to something a lot shorter or a lot longer. It will still behave same? – Kamil Klimek Feb 06 '12 at 09:09
  • Also if you target only one platform, then we can stop debate – Kamil Klimek Feb 06 '12 at 09:10
  • Yes, the length of the label doesn't matter. It is correctly formatted to the two columns. I hope you trust that I've verified this. The only difference is the underlined number denoting the mnemonic. – swalog Feb 06 '12 at 09:14
  • I'm targeting linux and windows platforms (although it also works fine on MAC, it is not a supported platform). Also, I wasn't aware of a debate taking place. I'll have to verify on the windows build. – swalog Feb 06 '12 at 09:16
  • I've checked your solution on Mac OS X. It doesn't work with mnemonics in "text\tCTRL+&1". Shortcut is invisible for that action. Please add this information to your answer, to make it complete – Kamil Klimek Feb 06 '12 at 09:20
  • Thank you for testing this on the Mac OS X, I will definitely add this to the answer. I've yet to test it on the windows platform (takes a looong time to compile on windows). I'll update once it's done. Thanks. – swalog Feb 06 '12 at 09:39
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/7378/discussion-between-exit-failure-and-kamil-klimek) – swalog Feb 06 '12 at 09:42