В Qt, как отображать сочетания клавиш в меню, но отключать их?

Я добавляю кучу QAction в меню моего главного окна. Эти действия также могут быть вызваны клавиатурой, и я хочу, чтобы ярлык был виден в меню, как обычно, например.

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

Я могу сделать это, используя QAction.setShortcut(). Однако я не хочу, чтобы эти QAction запускались ярлыками; Я обрабатываю весь ввод с клавиатуры отдельно в другом месте.

Это возможно? Могу ли я отключить ярлык в QAction, но по-прежнему иметь текст ярлыка (в этом примере Ctrl + C) в моих меню?

РЕДАКТИРОВАТЬ: в итоге я подключился к событиям aboutToShow() и aboutToHide() меню и включил/отключил ярлыки, чтобы они были активны только при отображении меню. Но я был бы признателен за более чистое решение...


person dF.    schedule 12.12.2009    source источник
comment
Просто ради интереса, почему вы обрабатываете весь ввод с клавиатуры где-то еще?   -  person Parker Coates    schedule 14.12.2009


Ответы (2)


Вы можете наследоваться от QAction и переопределить 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);
    }
};

Это приведет к тому, что любые события типа QEvent::Shortcut, отправленные вашим действиям, не будут запускать сигналы 'triggered()'.

person Idan K    schedule 12.12.2009
comment
Или, что еще лучше, используйте фильтр событий вместо создания подклассов. - person andref; 13.12.2009
comment
К сожалению, ни подкласс, ни фильтр событий у меня не работают; QAction не получает QShortcutEvent. Возможно это взаимодействие с какой-то другой частью программы, попробую выяснить. Тем временем я вернулся к своему первоначальному решению... - person dF.; 14.12.2009
comment
Я проверил это на Windows, и это сработало. возможно, попробуйте сделать это в новом проекте, это может быть проблема с платформой... - person Idan K; 14.12.2009
comment
Я пробую это на Mac - это должно быть либо проблема с платформой, либо что-то еще в моей программе. Спасибо хоть! - person dF.; 21.12.2009
comment
Я заметил некоторые несоответствия между платформами в этом поведении — см. мой комментарий к bugreports.qt .nokia.com/browse/QTBUG-12495. Может ли это иметь значение? - person jlarcombe; 05.11.2010

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

Это будет выглядеть как действие с ярлыком, но на самом деле ярлык не установлен.

Вот полный пример:

#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();
}
person baysmith    schedule 27.12.2009
comment
Фактически это устанавливает ярлык (Qt 4.6, mac) - person dF.; 25.04.2010
comment
В приведенном выше примере Ctrl+T закрывает приложение на Mac? В Qt 4.6 в Windows и Linux Ctrl+T не запускает действие. - person baysmith; 28.04.2010
comment
@dF Я тестировал это на WIndows 10, Qt 5.11.2, и это НЕ устанавливает ярлык. - person V.K.; 13.10.2018