Search code examples
qtribbonqactionqtabbarqtoolbar

Simple ribbon: how to use QActions within QTabBar?


I'm trying to implement simple tabbed interface with Qt5. I use QTabWidget with QToolBars placed inside its tabs and I add QActions to the QToolBars.

That works but causes the following issue: any action remains accessible only while its parent tab is active. If I try to use keyboard shortcut for currently "invisible" action, I will have no success. Since there's no menu etc, the tabs are the only place, where the actions are placed.

Here's how I add the elements to the toolbar:

QTabWidget *ribbon               = new QTabWidget(window);
QToolBar *tool_bar_game          = new QToolBar(tab_game);
QAction *action_go_to_next_level = new QAction(window);

action_go_to_next_level->setText(QApplication::translate("Window", "&Next", 0));
action_go_to_next_level->setIcon(QIcon::fromTheme("go-last"));
action_go_to_next_level->setShortcut(QApplication::translate("Window", "PgDown", 0));


ribbon->addTab(tool_bar_game, tr("Game"));
tool_bar_game->addAction(action_go_to_next_level);

and a screenshot:

Ribbon-like 2-tabs interface

How can I make the action accessible with shortcuts, even when the action's parent tab is not currently opened?


Solution

  • I'm not surprised that this doesn't work, effectively you try to use a shortcut on a hidden widget. It would be very confusing if this worked.

    The obvious workaround for this is to add the shortcut instead of to the QAction to a widget that is always active. Personally, I suggest the window.

    Without having tested the code, I believe this should work:

    QTabWidget *ribbon               = new QTabWidget(window);
    QToolBar *tool_bar_game          = new QToolBar(tab_game);
    QAction *action_go_to_next_level = new QAction(window);
    
    action_go_to_next_level->setText(QApplication::translate("Window", "&Next", 0));
    action_go_to_next_level->setIcon(QIcon::fromTheme("go-last"));
    
    QShortcut *page_down = new QShortcut(QKeySequence("PgDown"), window);
    // trigger the action when the shortcut is activated
    QObject::connect(page_down,               &QShortcut::activated,
                     action_go_to_next_level, &QAction::trigger);
    
    ribbon->addTab(tool_bar_game, tr("Game"));
    tool_bar_game->addAction(action_go_to_next_level);