×
Namespaces

Variants
Actions

Archived:Qt Menus

From Nokia Developer Wiki
Jump to: navigation, search

Archived.pngArchived: This article is archived because it is not considered relevant for third-party developers creating commercial solutions today. If you think this article is still relevant, let us know by adding the template {{ReviewForRemovalFromArchive|user=~~~~|write your reason here}}.

Qt C++ UIs are deprecated - QML should be used instead where possible.

his article provides a comprehensive explanation of how to create QMainWindow application menus in Qt on the Symbian platform. It includes information about how to change menu softkey text, how to use menu icons, and how to support menus in view switching applications.

Article Metadata
Compatibility
Platform(s):
Symbian
Article
Created: hamishwillee (17 Dec 2010)
Last edited: hamishwillee (30 Apr 2013)

It highlights the minor platform specific issues, and is intended to be complementary to the generic Qt Menus Example and reference documentation: QMainWindow, QMenu, QMenuBar, QAction, QActionGroup

Contents

Overview

Qt is a true cross platform application framework; Application menus are defined using platform-neutral classes that, when compiled, result in menus with the same look and feel as those written using native libraries.

On Symbian, Qt implements the menu using native menu libraries. While the menu specification is generic, this means that there are several considerations for Qt developers targeting Symbian platform devices:

  1. Some menu functionality that works on desktop is not supported on the Symbian platform
    • Icons cannot be displayed in menus or menu items - QTBUG-7951
    • Separators between menus/menu items aren't displayed
    • Menu actions that are disabled are made invisible rather than "greyed out"
    • Menu text cannot be styled (for example made bold or italic)
    • Context menus aren't supported (or needed)
    • Keyboard shortcuts and shortcut text aren't supported (or needed)
  2. Nesting of menus and menu items is discouraged
    • While Symbian applications can deeply nest menus, this can make them harder to use. It is more typical to have menu actions at the top level, or at most one level down.
  3. Qt supports menus only in the QMainWindow itself; applications that have several "views" on the application data must implement mechanisms to update the main window menu when the view changes.

Example code

The Nokia Menus Example demonstrates most aspects of using menus. Screenshots of the example running on Symbian and Windows (Vista) are shown below. The Symbian menu is selected by clicking the "Options" softkey. The second and third screenshots show the nested menus. Note the styling that is missing from the "Bold" and "Italic" menu items, along with the separators and keyboard accelerators.

Menus example on Windows Vista

While the example is useful it does omit a number of menu related topics:

  1. Having actions/menu items as the top level menu
  2. Changing the "Options" softkey text used to launch the menu
  3. Changing the "Options" softkey text to an icon
  4. Having icons as menu items
  5. Code to remove spurious "Actions" menu from the top level menu options

These, along with the general use of menus are explained in the following sections.

Ensuring the menu is displayable

The "Options" softkey must be visible in order to select the menu. In order to ensure that the softkeys are not covered by the main window the menu example calls QMainWindow::showMaximized() to size the window to fit between the softkeys at the bottom of the screen and the status up the top:

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow window;
#if defined(Q_OS_SYMBIAN)
window.showMaximized();
#else
window.show();
#endif
return app.exec();
}

Its also possible to just expose the softkeys (hide the status pane) by setting the window to be full screen and providing a windows hint. This is discussed in Qt Softkeys.

How to create a menu

Symbian application with top level options
Most Symbian applications use top level menu actions (QAction) which are added directly to the main windows menu bar (QMainWindow::menuBar()), as shown on the image to the right.

Menu actions are created using QAction; these are connected to the appropriate slot, and then added to a QMenuBar

//Create actions with the main window as parent
QAction* myAction1=new QAction(tr("Option 1"), this);
QAction* myAction2=new QAction(tr("Option 2"), this);
//Connect the actions to slots in your main window
connect(myAction1, SIGNAL(triggered()), this, SLOT(mySlotFunction1()));
connect(myAction2, SIGNAL(triggered()), this, SLOT(mySlotFunction2()));
//Add the actions to the menubar (or a menu)
menuBar()->addAction(myAction1);
menuBar()->addAction(myAction2);

Note that the QAction is created using the tr function in order to ensure that the menu text is visible to Qt's translation system. If the code is not to run on desktops there is no need to declare shortcuts in the text or add any styling.

The menuBar takes ownership of the action; if you don't need to keep a handle to the action for later use, you can create the action and its signal/slot connections and add it to the menubar in one go:

menuBar()->addAction("Option 1", this, SLOT(mySlotFunction()));

We can also add menus/nested menus to the tree. The menu example shows this:

//Call addMenu on the menuBar to get a QMenu*
editMenu = menuBar()->addMenu(tr("&Edit"));
//Add actions to the menu
editMenu->addAction(undoAct);
editMenu->addAction(redoAct);
...
 
helpMenu = menuBar()->addMenu(tr("&Help"));
helpMenu->addAction(aboutAct);
helpMenu->addAction(aboutQtAct);

Note that the menuy softkey "Options" appears as soon as you create the first menu item.

How to remove the spurious "Actions" menu

The menu example does not have any focussable widgets. When you create a real application it probably will, and if you select one of these and then open the menu, you'll see a menu item labeled "Actions". This is a placeholder for the widget context menu, which isn't needed on Symbian applications.

You can individually call setContextMenuPolicy(Qt::NoContextMenu) on every widget to remove this item; however it is usually easier to call it on all widgets in the application in your main() function:

/* Remove context menu from the all widgets. */
QWidgetList widgets = QApplication::allWidgets();
QWidget* w=0;
foreach(w,widgets) {
w->setContextMenuPolicy(Qt::NoContextMenu);
}

How to disable a menu item

A QAction can be disabled or made invisible using the methods QAction::setDisabled() and QAction::setDisabled(). On desktop platforms the distinction is that the action remains visible but greyed out if it is disabled - on the Symbian platform either approach will make the item invisible.

How to "check" a menu item(s)

Menu items can be "checked" - on the Symbian platform they are displayed with a "tick" mark next to them. To make a menu action checkable you need to call setCheckable(true) on it. You can then set it as checked using setChecked(true):

QAction* checkableAction = new QAction(tr("Checkable"), this);
//Set as checkable
checkableAction ->setCheckable(true);
 
//Set this action as checked
checkableAction ->setChecked(true);
menuBar()->addAction(checkableAction);

Sometimes you need to create a group of menu actions where only one is selectable - equivalent to a single selection radio button. This can be done using the QActionGroup, as demonstrated in the menu example:

alignmentGroup = new QActionGroup(this);
alignmentGroup->addAction(leftAlignAct);
alignmentGroup->addAction(rightAlignAct);
alignmentGroup->addAction(justifyAct);
alignmentGroup->addAction(centerAct);
leftAlignAct->setChecked(true);

Note.pngNote: There is a bug in Qt QTBUG-14663 (4.6.3) that the check mark is not shown in top level menu items. The action still accurately reports its check state in code

How do I change the menu softkey text

The default menu softkey will use the equivalent of "Options" appropriate for the current phone language. You can change this text by adding your own menu, as shown below:

QMenu* menu = new QMenu(this);
menu->addAction("Option 1", this, SLOT(menuItemTriggered()));
menu->addAction("Option 2", this, SLOT(menuItemTriggered()));
menu->addAction("Option 3", this, SLOT(menuItemTriggered()));
 
QAction* myMenuKey = new QAction("MyMenu", this);
myMenuKey->setSoftKeyRole(QAction::PositiveSoftKey);
myMenuKey->setMenu(menu);
addAction(myMenuKey );

Note however that the default menu text is localized on your behalf; if you change it then you may need to provide your own translations (a better alternative if the default text is unacceptable may be to use an image for the softkey).

How to add an icon to a menu action

Not supported at present. See https://bugreports.qt-project.org/browse/QTBUG-7951

How to add an icon to the menu softkey

You can't simply add an icon to the default menu softkey because its QAction is internal. Instead you first need to create a new menu/menu softkey, as discussed in #How do I change the menu softkey text and then you add a softkey icon, as discussed in Qt Softkeys#How to use softkey icons.

QMenu* menu = new QMenu(this);
menu->addAction("Option 1", this, SLOT(menuItemTriggered()));
menu->addAction("Option 2", this, SLOT(menuItemTriggered()));
menu->addAction("Option 3", this, SLOT(menuItemTriggered()));
 
QAction* myMenuKey = new QAction("MyMenu", this);
myMenuKey->setSoftKeyRole(QAction::PositiveSoftKey);
myMenuKey->setIcon(QPixmap(":/icons/icons/menu_icon.png")); //add icon for the menu softkey!
myMenuKey->setMenu(menu);
addAction(myMenuKey );


How to support menus in a view switching application

Symbian applications often have many different "views", each with their own context sensitive options menu. For example, a contact application would have a top level view to display contacts and a menu that defines selection operations. Once you're editing a contact the options available on the menu will be quite different.

In a Qt application this sort of behaviour requires some additional implementation, because while any widget can have a menubar or menu, only the menu belonging to the QMainWindow itself is displayed. There are a number of ways this can be handled. One way is to have a view switching architecture where the view sends a signal with its actions to the main window.

An alternative is to have an architecture where each "view" widget has its own menu. When a view is displayed the main window clears the menu and repopulates itself with items from the current widget's menu. This approach is used in the Nokia Developer QStackableWidget example.

[--hamishwillee : Provide link to example and some code fragments?]

Qt Creator

Qt Creator allows you to create menus and menu actions "visually" using Qt Designer, by nesting actions and menus within menus. This may not be suitable for Symbian applications because there is no way to specify that a top level menu item is an action rather than a menu.

Pushbutton menus

You can define a context menu that appears below a button when it is activated (for example, when it is pressed). This differs from a context menu, which is usually activated by a right mouse click.

The code fragment shows how to add the menu to a push button that has been defined using the Qt Creator UI Designer, and then launch it when the button is clicked:

QMenu* menu = new QMenu(this);
menu->addAction("Option 1", this, SLOT(menuItemTriggered()));
menu->addAction("Option 2", this, SLOT(menuItemTriggered()));
menu->addAction("Option 3", this, SLOT(menuItemTriggered()));
 
ui->pushButton->setMenu (menu );
connect(ui->pushButton,SIGNAL(clicked()),ui->pushButton,SLOT(showMenu()));

Summary

Qt menus on the Symbian platform are defined in the same way as on any other platform. However the menu itself is rendered quite differently than on desktop and some features do not behave as well (or at all) in a mobile context. This article has shown how menus work in standard Qt on Symbian applications, and what menu behaviour does not work.


Licence icon cc-by-sa 3.0-88x31.png© 2010 Symbian Foundation Limited. This document is licensed under the Creative Commons Attribution-Share Alike 2.0 license. See http://creativecommons.org/licenses/by-sa/2.0/legalcode for the full terms of the license.
Note that this content was originally hosted on the Symbian Foundation developer wiki.

This page was last modified on 30 April 2013, at 05:43.
90 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×