Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Qt, how to show keyboard shortcuts in menu but disable them?

I'm adding a bunch of QActions to my main window's menus. These actions can also be triggered by the keyboard, and I want the shortcut to be visible in the menu, as usual, e.g.

-----------------
|Copy     Ctrl+C|
-----------------

I can do this using QAction.setShortcut(). However, I don't want these QActions to be triggered by the shortcuts; I'm handling all keyboard input separately elsewhere.

Is this possible? Can I disable the shortcut in the QAction but still have the shortcut text (in this example Ctrl + C) in my menus?

EDIT: The way I ended up doing it is connecting to the menu's aboutToShow() and aboutToHide() events, and enabling/disabling the shortcuts so they are only active when the menu is shown. But I'd appreciate a cleaner solution...

like image 670
dF. Avatar asked Dec 12 '09 19:12

dF.


2 Answers

You could inherit from QAction and override QAction::event(QEvent*):

class TriggerlessShortcutAction : public QAction
{
public:
    ...ctors...

protected:
    virtual bool event(QEvent* e)
    {
        if (e->type() == QEvent::Shortcut)
            return true;
        else
            return QAction::event(e);
    }
};

This will cause any events of type QEvent::Shortcut sent to your actions to not trigger the 'triggered()' signals.

like image 179
Idan K Avatar answered Sep 25 '22 03:09

Idan K


action.setText("Copy\tCtrl+C");

This will look like an action with a shortcut, but the shortcut is not actually installed.

Here is a full example:

#include <QtGui>

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);

    QMainWindow win;

    QMenu *menu = win.menuBar()->addMenu("Test");

    // This action will show Ctrl+T but will not trigger when Ctrl+T is typed.
    QAction *testAction = new QAction("Test\tCtrl+T", &win);
    app.connect(testAction, SIGNAL(triggered(bool)), SLOT(quit()));
    menu->addAction(testAction);

    // This action will show Ctrl+K and will trigger when Ctrl+K is typed.
    QAction *quitAction = new QAction("Quit", &win);
    quitAction->setShortcut(Qt::ControlModifier + Qt::Key_K);
    app.connect(quitAction, SIGNAL(triggered(bool)), SLOT(quit()));
    menu->addAction(quitAction);

    win.show();

    return app.exec();
}
like image 20
baysmith Avatar answered Sep 26 '22 03:09

baysmith