(Difference between revisions)

Porting Symbian Qt Apps to Nokia N9

From Nokia Developer Wiki
Jump to: navigation, search
Tomi_ (Talk | contribs)
(Tomi -)
Tomi_ (Talk | contribs)
(Tomi -)
Line 448: Line 448:
* [http://projects.developer.nokia.com/QMLRestaurantApp Diner]
* [http://projects.developer.nokia.com/QMLRestaurantApp Diner]
* [http://projects.developer.nokia.com/rentbook RentBook]
* [http://projects.developer.nokia.com/rentbook RentBook]
* [https://projects.developer.nokia.com/QMLRSSReader RSS Reader]
* [http://projects.developer.nokia.com/QMLRSSReader RSS Reader]
* [http://projects.developer.nokia.com/tictactoe Tic-Tac-Toe over Sockets] (ported original from Windows Phone to Qt Quick)
* [http://projects.developer.nokia.com/tictactoe Tic-Tac-Toe over Sockets] (ported original from Windows Phone to Qt Quick)

Revision as of 16:21, 13 October 2011

This article explains how to port Symbian Qt applications to MeeGo 1.2 Harmattan platform. If you are already familiar with development on Harmattan and wish to port your application to Symbian, most of the methods described in this article apply also the other way around.

Article Metadata
Created: ()
Last edited: Tomi_ (13 Oct 2011)



  • Basics of mobile Qt development (Symbian or Harmattan)
  • Familiar with Qt SDK

In case you haven't yet developed for Harmattan, please take a look at Getting started with Harmattan section at MeeGo 1.2 Harmattan Development Documentation for information on e.g. selecting the proper target and setting up the emulator or the device in Qt SDK.


In general, regardless of the application type (whether it's a Qt Quick app or an OpenGL ES game, does not matter) as long as it's not implemented solely with native code, three approaches to porting the app exist:

  1. Make the necessary changes to the Symbian application code base to make it fully cross-platform i.e. same code base works both on Symbian and Harmattan.
  2. Rewrite the application to Harmattan. Utilize what you can from the Symbian application code.
  3. Compromise of the two previous approaches (and usually the best choise): Extract the cross-platform parts of the application and rewrite the platform specific parts to Harmattan.

The first approach is especially suitable for OpenGL ES games and applications although some tweaks are required to port the app (e.g. audio related implementation). The approach is also feasible if the application user interface is already scalable and does not contain platform specific components. Even if the aforementioned requirements are not met, it is possible to make the same code base work on both platforms but the work required to do this might be extensively more than rewriting would cause. See the Nokia Developer examples ported by following the first approach:

Rewriting the application (engine and/or UI) could be the best approach if the Symbian application has a QWidget based UI or the application logic in general is quite old and may contain a lot of Symbian/C++ native code. With Qt Quick apps a complete rewrite is practically never required and thus, this approach is not covered by this article.

The third approach works in most of the cases, especially for apps utilizing the Qt Quick components. The approach is covered step-by-step in the next section of this article. If you have troubles selecting between the first and this last approach, please read this Qt Quick components related blog article by Attila Csipa.

Porting Step-By-Step

Step 1: Refactoring project structure

For clarity it is recommended to create separate folders for common, Symbian specific and Harmattan specific UI components (see the following figure). Note that the structure may not be displayed in Active projects window of the Qt SDK until the required modifications to the project file are done (see step 2).


First identify and extract common components (i.e. the files whose code fully works or can easily be made to work on both platforms) and move them into the 'common' folder. Here's an example from Sensor Gallery project: a custom TextLabel element that works on both platforms (note that some parts of the code are omitted):

import QtQuick 1.0
Rectangle {
property alias text: labelText.text
gradient: Gradient {
GradientStop { position: 0.0; color: "#555555" }
GradientStop { position: 1.0; color: "#222222" }
// Inner rectangle to make borders
Rectangle {
Text {
id: labelText

After the common parts have been extracted, the Symbian specific QML and Javascript code can be moved to 'symbian' folder. Then just copy the files from 'symbian' folder to 'harmattan' folder. This will not provide you a working Harmattan UI (unless you're really, really lucky or talented in creating scalable and cross-platform QML code) but this is enough for now; we'll get to the required modifications in the later steps.

The application engine (implemented with Qt/C++) structure doesn't usually require changes. Platform specific variations can usually be handled using #ifdef blocks. Should an implementation of a class be completely different for Harmattan, utilizing interface classes and dynamic binding usually solves the issue:


#include <QObject>
#include "myinterface.h"
class MyClass : public QObject
explicit MyClass(QObject *parent = 0);
MyInterface *mMyImplementation;

In the header file declare a member variable pointer to a type of MyInterface in MyClass .

// Include the correct header depending on the target platform.
#include "mysymbianimplementation.h"
#include "myharmattanimplementation.h"

MyClass::MyClass(QObject *parent)
: QObject(parent),
mMyImplementation = new MySymbianImplementation(this);
mMyImplementation = new MyHarmattanImplementation(this);

In the source file (.cpp) construct a different instance depending on the target platform.

On how to define Harmattan specific code scope see here.

Step 2: Project file and application deployment

Add the Harmattan configurations into the project file. The following block contains the configurations in the project file of RentBook example (some parts omitted):

QT += core gui sql declarative
CONFIG += qt-components
TARGET = rentbook
src/main.cpp \
src/DatabaseManager.cpp \
src/DatabaseManager.h \
# Symbian specific
symbian {
message(Symbian build)
TARGET = RentBook
TARGET.UID3 = 0xea6c2793
TARGET.CAPABILITY += NetworkServices
TARGET.EPOCHEAPSIZE = 0x1000 0x1800000 # 24MB
ICON = icons/rentbook.svg
RESOURCES += resources.qrc
HEADERS += src/telephony_symbian.h
SOURCES += src/telephony_symbian.cpp
LIBS += -letel3rdparty
OTHER_FILES += qml/symbian/*.qml
qmlfiles.sources = qml
DEPLOYMENT += qmlfiles
# Harmattan specific
contains(MEEGO_EDITION, harmattan) {
message(Harmattan build)
HEADERS += src/telephony_stub.h
SOURCES += src/telephony_stub.cpp
target.path = /opt/usr/bin
INSTALLS += target
qmlfiles.path = /home/developer/rentbook/qml/
qmlfiles.files += qml/*
INSTALLS += qmlfiles
desktopfile.files = rentbook.desktop
desktopfile.path = /usr/share/applications
icon.files = icons/rentbook.png
icon.path = /usr/share/icons/hicolor/64x64/apps
INSTALLS += desktopfile icon
OTHER_FILES += qml/harmattan/*.qml

The Debian packaging files for Harmattan are created by Qt SDK. The desktop file is required to display the application launcher icon in the application menu on the device. The desktop file contains information such as the application title (shown in the application menu), the file name of the icon (without .png suffix) and path of the executable. The application launcher icon for Harmattan needs to be in PNG form and be the size of 80 x 80 pixels.

[Desktop Entry]

The desktop file content of RentBook example application.

The deployment options for the project can be set from the Projects tab page in Qt SDK (see the figure below).


If your application has audio and you want the hardware volume keys to control audio volume of your application, classify your application as a game. This can be achieved with the following steps:

1. Create <your application>.conf file (the following snippets are from AirSwype example).

[classify gaming] 

2. Add the following snippet into the Harmattan specific scope in the project file. This will deploy the .conf file with the application.

# Classify the application as a game to support volume keys on Harmattan.
gameclassify.files += qtc_packaging/debian_harmattan/airswype.conf
gameclassify.path = /usr/share/policy/etc/syspart.conf.d
INSTALLS += gameclassify

Step 3: First build

Before trying to build for the first time, remember to modify the main.cpp so that the correct QML file is loaded when application is launched (note that this is only required if the QML files are deployed onto the device instead of putting them into resources):

#if defined(Q_OS_SYMBIAN) || defined(Q_WS_SIMULATOR)
// Symbian and Simulator
// Harmattan

QML and Javascript files can be compiled into the binary using the Qt resource system. By using the resource system one does not have to deploy (i.e. copy) the QML files onto the device. However, due to a bug in Qt Quick 1.0 on Symbian QML files using the component icons cannot be placed in resources. The bug is fixed in Qt Quick 1.1 release for Symbian.

If the main QML file is loaded from resources and you have created separate resource files for both platforms, no changes are required:


Build the application using Harmattan target and fix any errors found. Build errors help you to find the platform specific code that needs to be rewritten for Harmattan. The #ifdef approach usually works.

Step 4: First run

If your Symbian Qt Quick application uses Qt Quick components 1.0 and components such as PageStack, StatusBar or ToolBar, you probably need to modify at least your main.qml of the Harmattan build. The following snippets from Sensor Gallery example show the possible differences in main.qml between Symbian and Harmattan:

import QtQuick 1.0
import com.nokia.symbian 1.0 // Symbian Qt Quick components
import "."
Window {
id: root
property int orientation: PageOrientation.Automatic
SensorListPage {
id: sensorListPage
orientationLock: root.orientation
// Common application statusbar
StatusBar {
id: statusBar
anchors.top: root.top
z: 1
// Page stack for all pages
PageStack {
id: pageStack
toolBar: toolBar
anchors {
left: parent.left
right: parent.right
top: statusBar.bottom
bottom: toolBar.top
Component.onCompleted: {
// Push the first page on the stack.
// Common toolbar for the pages
ToolBar {
id: toolBar
anchors.bottom: parent.bottom

main.qml for Symbian build.

import QtQuick 1.1
import com.nokia.meego 1.0 // Harmattan Qt Quick components
PageStackWindow {
id: root
property int orientation: PageOrientation.Automatic
showStatusBar: true
showToolBar: true
initialPage: SensorListPage {}
Component.onCompleted: {
// Use the dark theme.
theme.inverted = true;

main.qml for Harmattan build.

Note that with Qt Quick 1.1 Symbian components will also be equipped with PageStackWindow element.

Now, run/debug your application with emulator or on a device and locate the possible errors from the debug log. Fix also possible scaling issues since the resolution on Nokia N9 is significantly higher than in Symbian devices (854 x 480 vs. 640 x 360 [except 640 x 480 in Nokia E6-00]).

Step 5: Testing and fixing

No special tips or tricks exist for this step. Just keep testing and improving your new Harmattan version and when your application looks and behaves the way you want it to, don't forget to test that your original Symbian version still works.

If your application is using Qt Quick components, note that the component set does not match perfectly. For example, Qt Quick components 1.0 on Symbian lack the PageStackWindow element and Harmattan components version 1.0 lack the ListItem element which you need to implement yourself when porting an application (see the snippets below).

    Component { 
id: listDelegate
ListItem {
id: listItem
ListItemText {
x: platformStyle.paddingLarge
anchors.verticalCenter: listItem.verticalCenter
mode: listItem.mode
role: "Title"
text: name
subItemIndicator: true
onClicked: {
onPressAndHold : {

A list item delegate implemented with ListItem element on Symbian.

    Component {
id: listDelegate
Item {
id: listItem
width: listView.width
Rectangle {
radius: 8
anchors.fill: parent
opacity: 0.7
color: "#1874CD"
visible: itemMouseArea.pressed
Row {
x: 10
width: parent.width - 20
height: parent.height
Text {
width: listItem.width - arrowImage.width - 20
height: listItem.height
verticalAlignment: Text.AlignVCenter
font { family: platformLabelStyle.fontFamily; pixelSize: platformLabelStyle.fontPixelSize }
color: platformLabelStyle.textColor
text: name
Image {
id: arrowImage
y: (listItem.height - sourceSize.height) / 2
source: "image://theme/icon-m-common-drilldown-arrow"
+ (theme.inverted ? "-inverse" : "");
MouseArea {
id: itemMouseArea
anchors.fill: parent
onClicked: {
listView.currentIndex = index;
onPressAndHold : {
listView.currentIndex = index;

The same list item delegate implemented on Harmattan.


Nokia Developer Qt examples, hosted in Projects, that are ported using the approach covered in this section:

OpenGL ES Apps

OpenGL ES games and application require, in general, few changes. However, the setup around the native OpenGL ES code has to be changed. Fortunately, two set of APIs can help you port your application:

Qoat of the Hill example demonstrates the use of both the aforementioned APIs. Match'em Poker example is another OpenGL ES game which has been ported from iOS to Qt devices with Qt GameEnabler.


The approach for porting a Qt application depends on the type of the application and ultimately, the differences between the Symbian and the MeeGo 1.2 Harmattan platform such as native APIs and resolution. The work required may require the change of mere two to three lines of code or then it could be a full day's work. Fortunately, a complete rewrite is never required. When porting Qt Quick applications, especially implemented with Qt Quick components, keep in mind that the component set does not match perfectly on both platforms and some of the components may behave differently than on the other platform. In addition, try to make your QML UI elements scalable since the resolution is higher on Nokia N9.

Additional information

318 page views in the last 30 days.