Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries. Thanks for all your past and future contributions.

QML component ActionList

From Wiki
Jump to: navigation, search
Article Metadata
Tested with
SDK: Nokia Qt SDK 1.2
Devices(s): all devices, based on Symbian Anna, Nokia Belle
Platform(s): Symbian Anna, Nokia Belle
Device(s): All
Dependencies: None
Platform Security
Capabilities: None
Keywords: qml, ui
Created: Den123 (06 Mar 2012)
Last edited: Den123 (11 Mar 2012)


Let's examine ordinary application design. Almost always the main application screen contains information about main objects and allows access to main functionality. Traditionally, since AVKON, in such cases we use list as object-container. Example of such approach:

MBuddy portrait.png

Free space below the list is used for buttons, it's also a common solution for touch screens. As we can see, main screen in portrait mode satisfies all requirements of usability. However, if we change orientation of screen (or install the application on the phone with other proportions of the screen, such as Nokia E6) we will have problems:

MBuddy landscape.png

List takes all available space, no place for the buttons. Possible solutions of this problem:

  • We can place list and buttons inside Flickable. This decision is not good enough, because list already contains flickable content and list takes all available space.
  • We can change horizontal size of the list, place buttons on the right of the list. Such solution is possible, but this approach contradicts traditional style of Symbian apps: list should always occupies entire width of the screen.
  • We can transfer functions of the buttons in app menu. In this situation this approach is most appropriate. ActionList offers such functionality.

Code Snippet

ActionList component is responsible for compiling list of actions that can be represented as a set of buttons or (and) as a menu items.

Calculation of the components content is performed dynamically, depending on the size of the visible area:

  • if size permits, then every action takes the form of button
  • if there is no free place in visible area, then actions take the form of menu items (if menuLayout property is defined )

If you change height of the visible area, the contents of ActionList recompiles automatically.

To specify list of required actions, you should define property actionTitles:

actionTitles: [ qsTr( "Settings" ), qsTr( "Help" ), qsTr( "Other products" ) ]

For processing any actions from the list, you should define onProcessAction handler.

Source code, file ActionList.qml:

import QtQuick 1.1
import 1.1
Item {
id: root
property variant actionTitles: []
property variant menuLayout: null
signal processAction( int actionIndex )
onHeightChanged: {
var btnCount = Math.floor( Math.abs( root.height / ( __btnHeight + btnColumn.spacing ) ) )
if( btnCount > actionTitles.length )
btnCount = actionTitles.length
if( btnCount >= 0 && __curBtnCount !== btnCount )
console.log( "constructing objects..." )
for( var i = btnColumn.children.length - 1; i >= 0; i-- )
if( menuLayout != null )
for( i = menuLayout.children.length - 1; i >= 0; i-- ) {
var mnuItem = menuLayout.children[i]
if( "actionListIndex" in mnuItem ) // destroy only ActionList items
for ( i = 0; i < btnCount; i++ ) {
var btn = btnTemplate.createObject( btnColumn )
btn.text = actionTitles[ i ]
btn.actionListIndex = i
if( menuLayout != null ) {
for ( i = btnCount; i < actionTitles.length; i++ ) {
var newItem = mnuItemTemplate.createObject( menuLayout )
newItem.text = actionTitles[ i ]
newItem.actionListIndex = i
newItem.clicked.connect( menuLayout.clicked )
__curBtnCount = btnCount
Component {
id: btnTemplate
Button {
property int actionListIndex
anchors.left: parent.left
anchors.right: parent.right
onClicked: processAction( actionListIndex )
Component {
id: mnuItemTemplate
MenuItem {
property int actionListIndex
onClicked: {
processAction( actionListIndex )
Column {
id: btnColumn
anchors.fill: parent
spacing: platformStyle.paddingMedium
property int __btnHeight: privateStyle.buttonSize
property int __curBtnCount: -1

How to use:

Page {
id: mainPage
Rectangle {
id: area1
anchors.left: parent.left
anchors.right: parent.right
height: parent.height > parent.width ? parent.height * 0.6 : 280
Label {
text: "Area1"
color: "red"
anchors.centerIn: parent
ActionList {
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom area1.bottom
anchors.margins: platformStyle.paddingMedium
width: 340
actionTitles: [ "Action1", "Action2", "Action3", "Action4", "Action5" ]
menuLayout: window.mnuLayout
onProcessAction: {
console.log( "process action " + actionIndex );
This page was last modified on 11 March 2012, at 08:52.
44 page views in the last 30 days.