How to Port From Desktop to Mobile: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
 
No edit summary
Line 1: Line 1:
=How to Migrate Your Application from the Desktop to a Mobile Platform=
[[Category:Developing_with_Qt]]<br />[[Category:Qt Quick]]<br />[[Category:Developing with Qt::QtMobility]]<br />[[Category:HowTo]]<br />[toc align_right=&quot;yes&amp;quot; depth=&quot;3&amp;quot;]


This tutorial originally appeared on [http://wiki.qtlabs.org.br/doku.php?id=howto:desktoptomobile qtlabs.org.br.] ''[wiki.qtlabs.org.br]'' and was written by a team of developers from INdT.
= How to Migrate Your Application from the Desktop to a Mobile Platform =


==Introduction==
This tutorial originally appeared on &quot;qtlabs.org.br.&quot;:http://wiki.qtlabs.org.br/doku.php?id=howto:desktoptomobile and was written by a team of developers from INdT.


Developing for mobile devices require that you pay attention to some details, and migrating your destkop application to the mobile world can be hard if you don’t use the right tools and framework. Thanks to Qt and <span class="caps">QML</span>, this job can be easy and won’t demand too much time from the developer.
== Introduction ==
 
Developing for mobile devices require that you pay attention to some details, and migrating your destkop application to the mobile world can be hard if you don't use the right tools and framework. Thanks to Qt and QML, this job can be easy and won't demand too much time from the developer.


This tutorial aims at helping the developer that wants to migrate his desktop application to the mobile, giving tips about architectural changes in your application and mobile best practices.
This tutorial aims at helping the developer that wants to migrate his desktop application to the mobile, giving tips about architectural changes in your application and mobile best practices.


===About <span class="caps">QML</span>===
=== About QML ===


We will use a desktop application as an example during this tutorial and we will guide you during the migration of this example to a mobile version. We’ll use <span class="caps">QML</span>, the mark up language for Qt Quick, to build the mobile interface.
We will use a desktop application as an example during this tutorial and we will guide you during the migration of this example to a mobile version. We'll use QML, the mark up language for Qt Quick, to build the mobile interface.


<span class="caps">QML</span> provides the means for building dynamic, rich and custom user interfaces. It also improves the integration between JavaScript and [http://doc.qt.nokia.com/4.7/metaobjects.html#meta-object-system Qt’s Object system,] ''[doc.qt.nokia.com]'' allowing it to easily integrate with your C++ code.
QML provides the means for building dynamic, rich and custom user interfaces. It also improves the integration between JavaScript and &quot;Qt's Object system,&quot;:http://doc.qt.nokia.com/4.7/metaobjects.html#meta-object-system allowing it to easily integrate with your C++ code.


===About Qt Mobility===
=== About Qt Mobility ===


Qt Mobility is a set of Qt <span class="caps">API</span>s with features that are usually present on mobile devices, specially phones. Besides being <span class="caps">API</span>s that aim the mobile world, they support different backends, making it easy to develop applications for phones in the desktop. This avoid the “round-trips” between developing on desktop and testing on the phone, allowing the application’s development to be faster.
Qt Mobility is a set of Qt APIs with features that are usually present on mobile devices, specially phones. Besides being APIs that aim the mobile world, they support different backends, making it easy to develop applications for phones in the desktop. This avoid the &quot;round-trips&amp;quot; between developing on desktop and testing on the phone, allowing the application's development to be faster.


Examples of these <span class="caps">API</span>s are: bearer management, contacts, location, multimedia and sytem information. Basically, Qt Mobility will give you access to the phone features and its sensors.
Examples of these APIs are: bearer management, contacts, location, multimedia and sytem information. Basically, Qt Mobility will give you access to the phone features and its sensors.


===Canvas-based UIs===
=== Canvas-based UIs ===


While developing desktop applications using Qt the developer usually will use [http://doc.qt.nokia.com/4.7/qwidget.html QWidgets,] ''[doc.qt.nokia.com]'' which are widgets developed with the desktop in mind and that will look exactly like the “native” widgets of the platform. This also works for the mobile world but today it is more usual to find UIs that are rich and fluid.
While developing desktop applications using Qt the developer usually will use &quot;QWidgets,&quot;:http://doc.qt.nokia.com/4.7/qwidget.html which are widgets developed with the desktop in mind and that will look exactly like the &quot;native&amp;quot; widgets of the platform. This also works for the mobile world but today it is more usual to find UIs that are rich and fluid.


In order to properly have UIs that can be animated and that doesn’t look like the platform’s widgets, one should use a canvas based UI. Qt provides a canvas for developers called [http://doc.qt.nokia.com/4.7/qgraphicsview.html QGraphicsView] ''[doc.qt.nokia.com]''. One of the many differences between QGraphicsView’s interfaces and QWidget’s ones is that QWidget depends on the screen resolution and that if the developer chooses to use a canvas he must be aware that most of the common widgets are not yeat available out of the box, but that they can be easily built using pixmaps.
In order to properly have UIs that can be animated and that doesn't look like the platform's widgets, one should use a canvas based UI. Qt provides a canvas for developers called &quot;QGraphicsView&amp;quot;:http://doc.qt.nokia.com/4.7/qgraphicsview.html. One of the many differences between QGraphicsView's interfaces and QWidget's ones is that QWidget depends on the screen resolution and that if the developer chooses to use a canvas he must be aware that most of the common widgets are not yeat available out of the box, but that they can be easily built using pixmaps.


This gives extra freedom to the application’s designer as he can create all the elements of the screen and they will look like exactly the way they were designed. It is important to say that <span class="caps">QML</span> runs on top of QGraphicsView and that it eases the development of the user interfaces. However it is still possible to make everything in plain C++.
This gives extra freedom to the application's designer as he can create all the elements of the screen and they will look like exactly the way they were designed. It is important to say that QML runs on top of QGraphicsView and that it eases the development of the user interfaces. However it is still possible to make everything in plain C+''.
<br />This tutorial will focus in the use of QML and its integration with C, trying to keep all the logic in C''+ and just making your UI using QML. This is the easiest path if the developer needs to maintain a mobile version of an application at the same time that he maintains the desktop version.


This tutorial will focus in the use of <span class="caps">QML</span> and its integration with C++, trying to keep all the logic in C++ and just making your UI using <span class="caps">QML</span>. This is the easiest path if the developer needs to maintain a mobile version of an application at the same time that he maintains the desktop version.
=== Considerations about mobile UIs ===


===Considerations about mobile UIs===
You need to take special care related to the areas that will be &quot;clickable&amp;quot; in your application when you develop to a mobile device.


You need to take special care related to the areas that will be “clickable” in your application when you develop to a mobile device.
The &quot;clickable&amp;quot; areas of your application should be big enough to handle the &quot;average&amp;quot; finger size of someone and also you should not forget that the fingers used to interact with your application may vary depending on the device's orientation (landscape vs portrait).


The “clickable” areas of your application should be big enough to handle the “average” finger size of someone and also you should not forget that the fingers used to interact with your application may vary depending on the device’s orientation (landscape vs portrait).
Be sure to make the areas small enough to not overlap each other. Also avoid the device's corners as they are harder for the user to select. During design time, make sure you question yourself if the user is going to use your application with just one hand for example as this may change the user experience of your application.


Be sure to make the areas small enough to not overlap each other. Also avoid the device’s corners as they are harder for the user to select. During design time, make sure you question yourself if the user is going to use your application with just one hand for example as this may change the user experience of your application.
== Screen Resolution ==
 
==Screen Resolution==


When developing mobile applications, one thing to keep in mind and take care of is that: If you want your application to run on a wide range of devices, you have to cope with different screen resolutions, that have different properties and features. It is important to allow your application to be scalable to give the user the best experience possible on the specific device. Additionally, many devices support screen rotation when your application is running, so be prepared to dot it.
When developing mobile applications, one thing to keep in mind and take care of is that: If you want your application to run on a wide range of devices, you have to cope with different screen resolutions, that have different properties and features. It is important to allow your application to be scalable to give the user the best experience possible on the specific device. Additionally, many devices support screen rotation when your application is running, so be prepared to dot it.


When writing mobile applications, the developer must avoid using fixed size for items placed on the screen. Qt and <span class="caps">QML</span> provide ways to layout items that help you to deal with that. Take a look at the example below.
When writing mobile applications, the developer must avoid using fixed size for items placed on the screen. Qt and QML provide ways to layout items that help you to deal with that. Take a look at the example below.


The example above makes usage of anchors, in order to adapt the application size to screen resolution of the device. Additionally, is important to make your application starts on fullscreen, so the <span class="caps">QML</span> item above will anchor at QDeclarativeView, like the example below:
<code><br />/* main.qml '''/<br />Item {<br /> width: parent.width<br /> height: parent.height
<br /> Rectangle {<br /> id: rect<br /> width: 100<br /> height: 100<br /> color: &quot;red&amp;quot;
<br /> anchors.centerIn: parent
<br /> MouseArea {<br /> anchors.fill: parent<br /> onClicked: rect.color == &quot;red&amp;quot; ? rect.color = &quot;blue&amp;quot; : rect.color = &quot;red&amp;quot;<br /> }<br /> }<br />}<br /></code>
<br />The example above makes usage of anchors, in order to adapt the application size to screen resolution of the device. Additionally, is important to make your application starts on fullscreen, so the QML item above will anchor at QDeclarativeView, like the example below:
<br /><code><br />/''' main.cpp '''/<br />QDeclarativeView window;<br />window.showFullScreen();<br />window.setSource(QUrl::fromLocalFile&amp;amp;#40;&quot;main.qml&amp;quot;&amp;#41;);<br /></code>
<br />h2. Memory Management
<br />When dealing with mobile development, the developer must be aware that resources are very limited, e.g. CPU power and memory. So, when porting your desktop application to mobile world, memory management has to be seriously taken into account, since it can become a bottleneck on application execution.
<br />h3. Memory Allocation
<br />There are two ways that a user can allocate memory: Stack allocation and Heap allocation.
<br />Every time a program starts its memory is organized in the following segments:
<br />''' Text segment: The place where the program code is placed (the machine instructions)<br />* Stack segment: Reserved block of memory that gets allocated when a thread/function is started, in order to handle local variables and parameters<br />* Heap segment: Memory block that is reserved for dynamic allocation during the program execution


==Memory Management==
=== Heap ===


When dealing with mobile development, the developer must be aware that resources are very limited, e.g. <span class="caps">CPU</span> power and memory. So, when porting your desktop application to mobile world, memory management has to be seriously taken into account, since it can become a bottleneck on application execution.
The Heap segment is a big block of free memory where user can allocate portions of memory dynamically. For instance, in C a user can allocate memory in the heap using the malloc operator, however in C++ you use the new operator to allocate memory in the heap. The precise location of the requested memory is not known in advance, so those dynamic allocator operators return a pointer to user, in order to manage the allocated memory. Additionally, it is worth telling that continuous block of memory requested does not assure that a sequential block of memory is going to be allocated, this is due to memory fragmentation resulted by various memory allocation and deallocation operations.


===Memory Allocation===
=== Stack ===


There are two ways that a user can allocate memory: Stack allocation and Heap allocation.
Whenever a thread is started, a block of memory is allocated and given to it, in order to store its local variables and parameters. So, for instance when a C program starts (the main thread) it receives a block of memory, the Stack. When a function is called, a block of memory of this stack (on top of it) is reserved for that function to store its data and gets pushed on the Stack.


Every time a program starts its memory is organized in the following segments:
=== Example ===


* Text segment: The place where the program code is placed (the machine instructions)
<code><br />int main(int argc, char** argv)<br />{<br /> int a; // allocated on stack
* Stack segment: Reserved block of memory that gets allocated when a thread/function is started, in order to handle local variables and parameters
* Heap segment: Memory block that is reserved for dynamic allocation during the program execution


===Heap===
int b[10]; //allocated on the stack


The Heap segment is a big block of free memory where user can allocate portions of memory dynamically. For instance, in C a user can allocate memory in the heap using the malloc operator, however in C++ you use the new operator to allocate memory in the heap. The precise location of the requested memory is not known in advance, so those dynamic allocator operators return a pointer to user, in order to manage the allocated memory. Additionally, it is worth telling that continuous block of memory requested does not assure that a sequential block of memory is going to be allocated, this is due to memory fragmentation resulted by various memory allocation and deallocation operations.
int '''p = (int''') malloc(sizeof(int)); // allocated on the heap


===Stack===
return 0;<br />}<br /></code>


Whenever a thread is started, a block of memory is allocated and given to it, in order to store its local variables and parameters. So, for instance when a C program starts (the main thread) it receives a block of memory, the Stack. When a function is called, a block of memory of this stack (on top of it) is reserved for that function to store its data and gets pushed on the Stack.
In the example above variable //*'''a// and //b// (the whole array) get allocated on the stack. On the other hand, //p// gets dynamically allocated on the heap.
<br />When the thread/function exits, all the memory that was being used by it (local variables, parameters, etc…) gets automatically deallocated whereas all memory that was dynamically allocated must be explicitly deallocated by the user, or leaks of memory may appear.
<br />So, the code above would be better written like this:
<br /><code><br />int main(int argc, char'''* argv)<br />{<br /> int a; // allocated on stack


===Example===
int b[10]; // allocated on stack


In the example above variable //**a**// and //**b**// (the whole array) get allocated on the stack. On the other hand, //**p**// gets dynamically allocated on the heap.
int '''p = (int''') malloc(sizeof(int)); // allocated on the heap


When the thread/function exits, all the memory that was being used by it (local variables, parameters, etc…) gets automatically deallocated whereas all memory that was dynamically allocated must be explicitly deallocated by the user, or leaks of memory may appear.
free(p); // free memory on heap


So, the code above would be better written like this:
return 0;<br />}<br /></code>


===Heap Allocation vs Stack Allocation===
=== Heap Allocation vs Stack Allocation ===


Memory allocation on the stack is faster when compared to the heap.
Memory allocation on the stack is faster when compared to the heap.


When a memory block is requested to the heap, by new or malloc for instance, the dynamic memory operator starts seeking for an available amount of memory that fits the requested size. On the other hand, the stack size needed for a function is known beforehand. When the function is called a piece of the stack is reserved for the function and then all local variables and parameters are placed there. Additionally, the memory of the stack tends to be used very frequently, due to several function calls, thus it tends to be mapped to the processor’s cache, increasing cache hit ratio, which makes the access time shorter than the time spent to access some memory allocated at the heap, which you have higher probability to get a page fault.
When a memory block is requested to the heap, by new or malloc for instance, the dynamic memory operator starts seeking for an available amount of memory that fits the requested size. On the other hand, the stack size needed for a function is known beforehand. When the function is called a piece of the stack is reserved for the function and then all local variables and parameters are placed there. Additionally, the memory of the stack tends to be used very frequently, due to several function calls, thus it tends to be mapped to the processor's cache, increasing cache hit ratio, which makes the access time shorter than the time spent to access some memory allocated at the heap, which you have higher probability to get a page fault.


Thus, it is preferable to use stack allocation as much as possible when developing something mobile. However, beware that the stack has limited size depending on the platform (Symbian for instance have 8KB by default). Although the stack can be extended, allocating huge amount of memory on stack can cause a stack overflow and makes your program crash. To put in a nutshell, the developer must use memory allocation wisely, balancing between stack and heap, in order to make an fast application.
Thus, it is preferable to use stack allocation as much as possible when developing something mobile. However, beware that the stack has limited size depending on the platform (Symbian for instance have 8KB by default). Although the stack can be extended, allocating huge amount of memory on stack can cause a stack overflow and makes your program crash. To put in a nutshell, the developer must use memory allocation wisely, balancing between stack and heap, in order to make an fast application.


===Note on Symbian Platform===
=== Note on Symbian Platform ===


On Symbian you can explicitly set the size of both Stack and Heap sizes. This is done by using <span class="caps">EPOCSTACKSIZE</span> and <span class="caps">EPOCHEAPSIZE</span> statements at the .mmp file, or put on your .pro file of your Qt application, as described on the example below:
On Symbian you can explicitly set the size of both Stack and Heap sizes. This is done by using EPOCSTACKSIZE and EPOCHEAPSIZE statements at the .mmp file, or put on your .pro file of your Qt application, as described on the example below:


===Call by Value vs Call by Reference===
<code><br />/* app.pro '''/<br />QT ''= core gui network
<br />TARGET = myapp<br />TEMPLATE = app


Since mobile resources (<span class="caps">CPU</span> and memory) are very limited, unnecessary memory copies must be avoided by the developer. One important point to avoid such copies is to watch the way you pass parameters when calling functions. Calling functions by value makes a temporary copy of the object, that is being passed as parameter, in memory. This can take unnecessary space in memory and waste <span class="caps">CPU</span> cycles to create a copy of the object, when the same function call could be made by reference, saving that used memory. Thus, if a function call could be done by “call by reference” it is preferable to do it, in order to avoid unnecessary memory copy operations. C++ support call by reference by adding the &amp; operator to the parameters’ description of the function. C does not support call by reference, even when you create a function that receives a pointer that pointer is copied in memory, which is a great way to “simulate” call by reference in C.
<br />SOURCES''= main.cpp
<br />symbian {<br /> TARGET.UID3 = 0xeb22583b
<br /> TARGET.EPOCSTACKSIZE = 0x14000 # Stack will have 80kB<br /> TARGET.EPOCHEAPSIZE = 0x020000 0x800000 # Heap minimum of 128kB and maximum of 8MB<br />}<br /></code>
<br />h3. Call by Value vs Call by Reference
<br />Since mobile resources (CPU and memory) are very limited, unnecessary memory copies must be avoided by the developer. One important point to avoid such copies is to watch the way you pass parameters when calling functions. Calling functions by value makes a temporary copy of the object, that is being passed as parameter, in memory. This can take unnecessary space in memory and waste CPU cycles to create a copy of the object, when the same function call could be made by reference, saving that used memory. Thus, if a function call could be done by &quot;call by reference&amp;quot; it is preferable to do it, in order to avoid unnecessary memory copy operations. C++ support call by reference by adding the &amp; operator to the parameters' description of the function. C does not support call by reference, even when you create a function that receives a pointer that pointer is copied in memory, which is a great way to &quot;simulate&amp;quot; call by reference in C.
<br />Below are some examples:
<br /><code><br />class MyObject<br />{<br />public:
<br /> int i;<br />};
<br />struct myStruct {<br /> int i;<br />};
<br />void add(struct myStruct''' s)<br />{<br /> s-&gt;i+'';<br />}
<br />void add(MyObject &amp;obj)<br />{<br /> obj.i;<br />}
<br />int main(int argc, char** argv)<br />{<br /> MyObject o;<br /> o.i = 10;<br /> add(o); // called by reference
<br /> struct myStruct '''my = (struct myStruct''') malloc(sizeof(struct myStruct));<br /> add(my); // pointer &quot;my&amp;quot; is copied to the function add
<br /> return 0;<br />}<br /></code>
<br />h2. Screen Orientation
<br />Screen orientation is not supported before Qt 4.7.2. So some platform specific code is necessary to lock or unlock the device orientation if you are compiling with old versions of Qt. However, if you are using QtCreator to develop your applications, you don't need to worry about it, since it abstracts all the necessary code in a helper class.
<br />h3. Qt Creator Wizard
<br />While creating a new project, you will be prompted to choose what kind of orientation behavior your application will have. The default option is &quot;Automatically Rotate Orientation&amp;quot;. If your application is designed to work in just one screen orientation, you can choose one of the other options, which are &quot;Lock to Landscape Orientation&amp;quot; and &quot;Lock to Portrait Orientation&amp;quot;.
<br />[[Image:http://developer.qt.nokia.com/uploads/image_upload/b4.png|http://developer.qt.nokia.com/uploads/image_upload/b4.png]]
<br />h3. Platform-Specific Code
<br />If you need to use platform specific code to set the device orientation, you will need to add some ifdefs in your code. You can follow QtCreator approach extending a QWidget class and adding an extra method to abstract orientation changes. For example, to handle screen orientation for Symbian and Maemo devices you can create a helper class like the following:
<br /><code><br />// …
<br />#ifdef Q_OS_SYMBIAN<br />#include &lt;eikenv.h&amp;gt;<br />#include &lt;aknappui.h&amp;gt;<br />#endif
<br />ApplicationView::ApplicationView(QWidget *parent)<br /> : QDeclarativeView(parent)<br />{
<br />}
<br />void ApplicationView::setOrientation(ScreenOrientation orientation)<br />{<br />#if defined(Q_OS_SYMBIAN)<br /> if (orientation == ScreenOrientationAuto)<br /> return;
<br /> CAknAppUiBase::TAppUiOrientation uiOrientation;
<br /> if (orientation == ScreenOrientationLockPortrait)<br /> uiOrientation = CAknAppUi::EAppUiOrientationPortrait;<br /> else<br /> uiOrientation = CAknAppUi::EAppUiOrientationLandscape;
<br /> CAknAppUi '''ui = dynamic_cast&amp;lt;CAknAppUi'''&gt;(CEikonEnv::Static()<s>&gt;AppUi());<br /> TRAPD (error, if (ui) ui</s>&gt;SetOrientationL(uiOrientation); );
<br /> Q_UNUSED(error);<br />#elif defined(Q_WS_MAEMO_5)<br /> switch (orientation) {<br /> case ScreenOrientationLockPortrait:<br /> setAttribute(Qt::WA_Maemo5PortraitOrientation, true);<br /> break;<br /> case ScreenOrientationLockLandscape:<br /> setAttribute(Qt::WA_Maemo5LandscapeOrientation, true);<br /> break;<br /> default:<br /> setAttribute(Qt::WA_Maemo5AutoOrientation, true);<br /> break;<br /> }<br />#else<br /> Q_UNUSED(orientation);<br />#endif<br />}<br /></code>
<br />h3. Setting Orientation in Qt 4.7.2
<br />Some new attributes were added in Qt 4.7.2 to set screen orientation. They are as follows:
<br />* Qt::WA_LockPortraitOrientation: //Locks the widget to a portrait orientation, ignoring changes to the display's orientation with respect to the user//
<br />* Qt::WA_LockLandscapeOrientation: //Locks the widget to a landscape orientation, ignoring changes to the display's orientation with respect to the user//
<br />* Qt::WA_AutoOrientation: //Causes the widget to change orientation whenever the display changes orientation with respect to the user//
<br />'''Usage example:''' In order to lock screen orientation in portrait mode you can do as follows:
<br /><code><br />QDeclarativeView view;
<br />view.setAttribute(Qt::WA_LockPortraitOrientation);<br /></code>
<br />'''Important note:''' Currently these attributes are being used just for Symbian, but probably this will change in future releases to handle Maemo and other platforms as well
<br />h2. Qt Mobility APIs
<br />As said previously, on Introduction, Qt Mobility is a set of Qt APIs that allow developers to write applications that uses some mobile features (e.g. contacts, location and message service) easily and in a cross-platform way, which means that you only need to have Qt and Qt Mobility frameworks installed on your mobile device.
<br />With these APIs the developers can write applications that:
<br />* Are able to use location services provided by the mobile device, e.g. GPS.<br />* Can send SMS to other mobile device<br />* Can play musics/videos and manage multimedia content<br />* Are able to manage the mobile device contacts
<br />In order to use the Qt Mobility, the developer must use the Qt Mobility namespace on his project.
<br />Ex.:
<br /><code><br />#include &lt;QtGui/QMainWindow&amp;gt;<br />#include &lt;QTextEdit&amp;gt;<br />#include &lt;QTimer&amp;gt;<br />#include &lt;qgeopositioninfosource.h&amp;gt;<br />#include &lt;qgeosatelliteinfosource.h&amp;gt;<br />#include &lt;qmessagemanager.h&amp;gt;<br />#include &lt;qmessageservice.h&amp;gt;
<br />QTM_USE_NAMESPACE // Qt Mobility namespace
<br />class MainApp : public QMainWindow<br />{<br /> Q_OBJECT
<br />….<br />….<br /></code>
<br />Here are some Qt Mobility APIs
<br />h3. Service Framework
<br />Implement and find services that are available on the mobile device and perform some operations with them.
<br />h3. Messaging
<br />This API gives the user capabilities to handle SMS, MMS, e-mail and any other kind of &quot;messages&amp;quot; the mobile device can deal with.<br />User can send, search and sort messages, get notified when new messages arrive, compose messages, etc.
<br />h3. Bearer Management
<br />Manages the connectivity state of the mobile device to the network, this includes WLAN and 3G networks
<br />h3. Contacts
<br />Manages all contact information on the mobile device or remotely. With it, user can create, delete and edit contacts
<br />h3. Location
<br />Perform location based operations, like: Retrieve your current GPS location
<br />h3. Multimedia
<br />Manages multimedia content on the mobile device. User can play music and videos, record audio and manage FM radio, for instance.
<br />h3. System Information
<br />Retrieve some system information like Installed Softwares' Version, Features (hardware), Network Status, Display Information, Storage Information, Device Information (battery, profile, SIM card)
<br />h3. Sensors
<br />An API for accessing hardware sensors, like the accelerometer
<br />h3. Camera
<br />Control the camera, capturing images, videos, etc.
<br />When writing an application that uses any Qt Mobility API, the developer must add the respective //*'''domain'''*// to MOBILITY variable on the project's .pro file and add the &quot;mobility&amp;quot; option to CONFIG variable.
<br />Below is a table that lists the Qt Mobility domains and associate it with the respective value that must be added to the MOBILITY variable.
<br />|'''Domain'''|'''Value'''|<br />|&lt;. Bearer Management|&lt;. bearer|<br />|&lt;. Contacts|&lt;. contacts|<br />|&lt;. Location|&lt;. location|<br />|&lt;. Multimedia|&lt;. multimedia|<br />|&lt;. Messaging|&lt;. messaging|<br />|&lt;. Publish And Subscribe|&lt;. publishsubscribe|<br />|&lt;. Service Framework|&lt;. serviceframework|<br />|&lt;. Sensors|&lt;. sensors|<br />|&lt;. System Information|&lt;. systeminfo|<br />|&lt;. Versit|&lt;. versit|<br />|&lt;. Document Gallery|&lt;. gallery|<br />|&lt;. Organizer|&lt;. organizer|<br />|&lt;. Tactile Feedback|&lt;. feedback|


Below are some examples:
<br />For instance, if you want to write an application that uses Qt Mobility to send messages to some contact, stored on your device, your .pro would look like this:
<br /><code><br />/* app.pro '''/<br />QT ''= core gui network
<br />TARGET = myapp<br />TEMPLATE = app
<br />SOURCES''= main.cpp
<br />CONFIG ''= mobility # mobility option in CONFIG<br />MOBILITY''= messaging # domains used on application<br /> contacts<br /></code>
<br />h3. Note on Symbian Platform
<br />When developing for Symbian with Qt Mobility, you have to add the required capabilities that are required by the specified domains (for further information, take a look &quot;here&amp;quot;:http://wiki.forum.nokia.com/index.php/Capabilities).<br />So, for Symbian the .pro would look like this:
<br /><code><br />/''' app.pro */<br />QT''= core gui network


==Screen Orientation==
TARGET = myapp<br />TEMPLATE = app


Screen orientation is not supported before Qt 4.7.2. So some platform specific code is necessary to lock or unlock the device orientation if you are compiling with old versions of Qt. However, if you are using QtCreator to develop your applications, you don’t need to worry about it, since it abstracts all the necessary code in a helper class.
SOURCES ''= main.cpp
<br />CONFIG''= mobility # mobility option in CONFIG<br />MOBILITY ''= messaging # domains used on application<br /> contacts
<br />symbian: {<br /> TARGET.CAPABILITY = ReadUserData # Symbian capabilities<br /> WriteUserData  NetworkServices<br />}<br /></code>


===Qt Creator Wizard===
<br />h2. Porting a Desktop Application to Mobile
<br />Let's pick one of the Qt examples to guide our study: the &quot;calculator&amp;quot;:http://doc.qt.nokia.com/4.7/widgets-calculator.html
<br />This example uses QWidgets to build a typical desktop interface. Besides that, the code has the logic strongly coupled to the UI definition, what is not the ideal scenario for porting an application to a different screen size and requires some modifications in the original code.
<br />h3. UI and Reusable Logic
<br />Let's take a look at Calculator, the main class in this example:
<br /><code><br />class Calculator : public QDialog<br />{<br /> Q_OBJECT
<br />public:<br /> Calculator(QWidget *parent = 0);
<br />private slots:<br /> void digitClicked();<br /> void unaryOperatorClicked();<br /> void additiveOperatorClicked();<br /> void multiplicativeOperatorClicked();<br /> void equalClicked();<br /> void pointClicked();<br /> void changeSignClicked();<br /> void backspaceClicked();<br /> void clear();<br /> void clearAll();<br /> void clearMemory();<br /> void readMemory();<br /> void setMemory();<br /> void addToMemory();
<br />private:<br /> Button *createButton(const QString &amp;text, const char *member);<br /> void abortOperation();<br /> bool calculate(double rightOperand, const QString &amp;pendingOperator);
<br /> double sumInMemory;<br /> double sumSoFar;<br /> double factorSoFar;<br /> QString pendingAdditiveOperator;<br /> QString pendingMultiplicativeOperator;<br /> bool waitingForOperand;
<br /> QLineEdit *display;
<br /> enum { NumDigitButtons = 10 };<br /> Button *digitButtons[NumDigitButtons];<br />};<br /></code>
<br />The Calculator class inherits &quot;QDialog,&quot;:http://doc.qt.nokia.com/4.7/qdialog.html contains the calculator buttons and display. It also contains several slots responsible for processing the inputs and calculating the results.<br />With such scenario, our first task is to separate the UI from the logic.
<br />To make things clearer for the sequence of this tutorial, we simplified a bit the original code of this example. Instead of using the createButton() method, we preferred to make all the creation and connections explicit.
<br />We are going to create a new class for the calculator logic. Let's call it //CalculatorEngine//.<br />This class will receive the slots that were in the Calculator class and will provide a signal emitted everytime a new result is available. This is the interface used by the current QWidget UI and also for the new QML based UI.
<br /><code><br />class CalculatorEngine : public QObject<br />{<br /> Q_OBJECT
<br /> Q_PROPERTY(QString display READ getDisplay NOTIFY displayChanged)
<br />public:<br /> CalculatorEngine(QObject *parent = 0);
<br />public slots:<br /> void digitAdded(int digitValue);
<br /> void addition();<br /> void subtraction();<br /> void multiplication();<br /> void division();
<br /> void square();<br /> void power();<br /> void reciprocal();
<br /> void equal();<br /> void point();<br /> void changeSign();<br /> void backspace();<br /> void clear();<br /> void clearAll();<br /> void clearMemory();<br /> void readMemory();<br /> void setMemory();<br /> void addToMemory();<br /> void abortOperation();<br /> bool calculate(double rightOperand, const QString &amp;pendingOperator);<br />signals:<br /> void displayChanged(QString text);
<br />private:<br /> void additiveOperation(QString selectedOperator);<br /> void multiplicativeOperation(QString selectedOperator);<br /> void unaryOperation(QString selectedOperator);
<br /> QString display;<br /> double sumInMemory;<br /> double sumSoFar;<br /> double factorSoFar;<br /> QString pendingAdditiveOperator;<br /> QString pendingMultiplicativeOperator;<br /> bool waitingForOperand;<br />};<br /></code>
<br />QML code can invoke slots and Q_INVOKABLE methods declared in C''+. It is well described in &quot;this section&amp;quot;:http://doc.qt.nokia.com/4.7-snapshot/qtbinding.html#embedding-c-objects-into-qml-components of the Qt documentation.


While creating a new project, you will be prompted to choose what kind of orientation behavior your application will have. The default option is “Automatically Rotate Orientation”. If your application is designed to work in just one screen orientation, you can choose one of the other options, which are “Lock to Landscape Orientation” and “Lock to Portrait Orientation”.
Our new Calculator class without all the logic part looks like this:
 
[[Image:b4.png]]
 
===Platform-Specific Code===
 
If you need to use platform specific code to set the device orientation, you will need to add some ifdefs in your code. You can follow QtCreator approach extending a QWidget class and adding an extra method to abstract orientation changes. For example, to handle screen orientation for Symbian and Maemo devices you can create a helper class like the following:
 
===Setting Orientation in Qt 4.7.2===
 
Some new attributes were added in Qt 4.7.2 to set screen orientation. They are as follows:
 
* Qt::WA_LockPortraitOrientation: //Locks the widget to a portrait orientation, ignoring changes to the display’s orientation with respect to the user//
 
* Qt::WA_LockLandscapeOrientation: //Locks the widget to a landscape orientation, ignoring changes to the display’s orientation with respect to the user//
 
* Qt::WA_AutoOrientation: //Causes the widget to change orientation whenever the display changes orientation with respect to the user//
 
'''Usage example:''' In order to lock screen orientation in portrait mode you can do as follows:
 
'''Important note:''' Currently these attributes are being used just for Symbian, but probably this will change in future releases to handle Maemo and other platforms as well
 
==Qt Mobility <span class="caps">API</span>s==


As said previously, on Introduction, Qt Mobility is a set of Qt <span class="caps">API</span>s that allow developers to write applications that uses some mobile features (e.g. contacts, location and message service) easily and in a cross-platform way, which means that you only need to have Qt and Qt Mobility frameworks installed on your mobile device.
<code><br />class Calculator : public QDialog<br />{<br />public:<br /> Calculator(QWidget *parent = 0);


With these <span class="caps">API</span>s the developers can write applications that:
private:<br /> QLineEdit *display;


* Are able to use location services provided by the mobile device, e.g. <span class="caps">GPS</span>.
enum { NumDigitButtons = 10 };<br /> Button *digitButtons[NumDigitButtons];
* Can send <span class="caps">SMS</span> to other mobile device
* Can play musics/videos and manage multimedia content
* Are able to manage the mobile device contacts


In order to use the Qt Mobility, the developer must use the Qt Mobility namespace on his project.
CalculatorEngine *engine;<br />};<br /></code>


Ex.:
Now Calculator contains the visual elements: 10 Buttons (which inherits &quot;QToolButton&amp;quot;:http://doc.qt.nokia.com/4.7/qtoolbutton.html) and a &quot;QLineEdit.&quot;:http://doc.qt.nokia.com/4.7/qlineedit.html The class implementation now concentrates in the creation and layout of the UI. All the logic was moved to &lt;code&amp;gt;CalculatorEngine&amp;lt;/code&amp;gt;, which inherits QObject and has the slots used by Calculator to connect its signals.
 
Here are some Qt Mobility <span class="caps">API</span>s
 
===Service Framework===
 
Implement and find services that are available on the mobile device and perform some operations with them.
 
===Messaging===
 
This <span class="caps">API</span> gives the user capabilities to handle <span class="caps">SMS</span>, <span class="caps">MMS</span>, e-mail and any other kind of “messages” the mobile device can deal with.<br /> User can send, search and sort messages, get notified when new messages arrive, compose messages, etc.
 
===Bearer Management===
 
Manages the connectivity state of the mobile device to the network, this includes <span class="caps">WLAN</span> and 3G networks
 
===Contacts===
 
Manages all contact information on the mobile device or remotely. With it, user can create, delete and edit contacts
 
===Location===
 
Perform location based operations, like: Retrieve your current <span class="caps">GPS</span> location
 
===Multimedia===
 
Manages multimedia content on the mobile device. User can play music and videos, record audio and manage FM radio, for instance.
 
===System Information===
 
Retrieve some system information like Installed Softwares’ Version, Features (hardware), Network Status, Display Information, Storage Information, Device Information (battery, profile, <span class="caps">SIM</span> card)
 
===Sensors===
 
An <span class="caps">API</span> for accessing hardware sensors, like the accelerometer
 
===Camera===
 
Control the camera, capturing images, videos, etc.
 
When writing an application that uses any Qt Mobility <span class="caps">API</span>, the developer must add the respective //**domain**// to <span class="caps">MOBILITY</span> variable on the project’s .pro file and add the “mobility” option to <span class="caps">CONFIG</span> variable.
 
Below is a table that lists the Qt Mobility domains and associate it with the respective value that must be added to the <span class="caps">MOBILITY</span> variable.
 
{| class="infotable line"
| '''Domain'''
| '''Value'''
|-
| style="text-align: left" | Bearer Management
| style="text-align: left" | bearer
|-
| style="text-align: left" | Contacts
| style="text-align: left" | contacts
|-
| style="text-align: left" | Location
| style="text-align: left" | location
|-
| style="text-align: left" | Multimedia
| style="text-align: left" | multimedia
|-
| style="text-align: left" | Messaging
| style="text-align: left" | messaging
|-
| style="text-align: left" | Publish And Subscribe
| style="text-align: left" | publishsubscribe
|-
| style="text-align: left" | Service Framework
| style="text-align: left" | serviceframework
|-
| style="text-align: left" | Sensors
| style="text-align: left" | sensors
|-
| style="text-align: left" | System Information
| style="text-align: left" | systeminfo
|-
| style="text-align: left" | Versit
| style="text-align: left" | versit
|-
| style="text-align: left" | Document Gallery
| style="text-align: left" | gallery
|-
| style="text-align: left" | Organizer
| style="text-align: left" | organizer
|-
| style="text-align: left" | Tactile Feedback
| style="text-align: left" | feedback
|}
 
For instance, if you want to write an application that uses Qt Mobility to send messages to some contact, stored on your device, your .pro would look like this:
 
===Note on Symbian Platform===
 
When developing for Symbian with Qt Mobility, you have to add the required capabilities that are required by the specified domains (for further information, take a look [http://wiki.forum.nokia.com/index.php/Capabilities here] ''[wiki.forum.nokia.com]'').<br /> So, for Symbian the .pro would look like this:
 
==Porting a Desktop Application to Mobile==
 
Let’s pick one of the Qt examples to guide our study: the [http://doc.qt.nokia.com/4.7/widgets-calculator.html calculator] ''[doc.qt.nokia.com]''
 
This example uses QWidgets to build a typical desktop interface. Besides that, the code has the logic strongly coupled to the UI definition, what is not the ideal scenario for porting an application to a different screen size and requires some modifications in the original code.
 
===UI and Reusable Logic===
 
Let’s take a look at Calculator, the main class in this example:
 
The Calculator class inherits [http://doc.qt.nokia.com/4.7/qdialog.html QDialog,] ''[doc.qt.nokia.com]'' contains the calculator buttons and display. It also contains several slots responsible for processing the inputs and calculating the results.<br /> With such scenario, our first task is to separate the UI from the logic.
 
To make things clearer for the sequence of this tutorial, we simplified a bit the original code of this example. Instead of using the createButton() method, we preferred to make all the creation and connections explicit.
 
We are going to create a new class for the calculator logic. Let’s call it //CalculatorEngine//.<br /> This class will receive the slots that were in the Calculator class and will provide a signal emitted everytime a new result is available. This is the interface used by the current QWidget UI and also for the new <span class="caps">QML</span> based UI.
 
<span class="caps">QML</span> code can invoke slots and Q_INVOKABLE methods declared in C++. It is well described in [http://doc.qt.nokia.com/4.7-snapshot/qtbinding.html#embedding-c-objects-into-qml-components this section] ''[doc.qt.nokia.com]'' of the Qt documentation.
 
Our new Calculator class without all the logic part looks like this:
 
Now Calculator contains the visual elements: 10 Buttons (which inherits [http://doc.qt.nokia.com/4.7/qtoolbutton.html QToolButton] ''[doc.qt.nokia.com]'') and a [http://doc.qt.nokia.com/4.7/qlineedit.html QLineEdit.] ''[doc.qt.nokia.com]'' The class implementation now concentrates in the creation and layout of the UI. All the logic was moved to <code>CalculatorEngine</code>, which inherits QObject and has the slots used by Calculator to connect its signals.


With the original code refactored, we have two clearly separated parts of the application: the current desktop UI and the internal logic. The logic part will be reused in the mobile version of the application.
With the original code refactored, we have two clearly separated parts of the application: the current desktop UI and the internal logic. The logic part will be reused in the mobile version of the application.


===Reusing Existing Models from standard Qt in <span class="caps">QML</span>===
=== Reusing Existing Models from standard Qt in QML ===
 
If your application has a proper separation between the UI and it’s logic the transition should not be hard and the UI will be the unique code rewritten. To port your app to <span class="caps">QML</span> there are two basic steps to do.
 
The first one is to create a [http://doc.qt.nokia.com/4.7/qdeclarativeview.html QDeclarativeView] ''[doc.qt.nokia.com]'' and make it load the root <span class="caps">QML</span> element of your application. The second is to export your current application logic to let <span class="caps">QML</span> use it.
 
The following snippet loads the Calculator.qml element and makes our <code>CalculatorEngine</code> visible to <span class="caps">QML</span> through the id <code>calcEngine</code>.
 
Now that we have a CalculatorEngine object visible in <span class="caps">QML</span> context we must use its properties, slots and signals to link with our UI.<br /> In our example, the <span class="caps">QML</span> code binds the display property from the model into a text element that we call Display.<br /> Javascript is also used to map the buttons in the layout with the actions that must be performed, calling the methods which the CalculatorEngine exports to <span class="caps">QML</span>.
 
===Using the Qt Resource System===
 
Qt provides a platform-independent resource system, useful to store important files needed by the application. It is a good option to guarantee the deployment and to avoid problems due to the corruption of one of these files.<br /> The Qt Resource System can generate a binary containing the files, then the application loads the content from this binary. Another possibility is to embed this generated resource file into the application binary. In this example, we use the second option to embed the images and <span class="caps">QML</span> files – check calculator.qrc. For more details regarding can be found in the [http://doc.qt.nokia.com/4.7//resources.html Qt Resource System documentation] ''[doc.qt.nokia.com]''
 
===Deploying to Mobile using Nokia Qt <span class="caps">SDK</span>===
 
====Creating a new Mobile Application====


While creating a new application you will be prompted to choose what kind of application you are about to create. Choose Qt Quick application:
If your application has a proper separation between the UI and it's logic the transition should not be hard and the UI will be the unique code rewritten. To port your app to QML there are two basic steps to do.


[[Image:b1.png]]
The first one is to create a &quot;QDeclarativeView&amp;quot;:http://doc.qt.nokia.com/4.7/qdeclarativeview.html and make it load the root QML element of your application. The second is to export your current application logic to let QML use it.


Continue with the Wizard and choose what targets your application will have. If you want to deploy for Symbian and Maemo click in the respective checkbox.
The following snippet loads the Calculator.qml element and makes our &lt;code&amp;gt;CalculatorEngine&amp;lt;/code&amp;gt; visible to QML through the id &lt;code&amp;gt;calcEngine&amp;lt;/code&amp;gt;.


[[Image:b3.png]]
<code><br />int main(int argc, char *argv[])<br />{<br /> QApplication app(argc, argv);


In application options you can change some target variables. You can set at this time the icon your application will use in Symbian and Maemo platforms and also change the UID3 for Symbian.
CalculatorEngine calcEngine;<br /> QDeclarativeView view;<br /> QDeclarativeContext '''context = view.rootContext();<br /> context-&gt;setContextProperty(&quot;calcEngine&amp;quot;, &amp;calcEngine); // Exporting logic part of our application to QML<br /> view.setSource(QUrl(&quot;:Calculator.qml&amp;quot;)); // Set the QML file that is inside a Qt Resource file<br /> view.show();
<br /> return app.exec&amp;amp;#40;&amp;#41;;<br />}<br /></code>
<br />Now that we have a CalculatorEngine object visible in QML context we must use its properties, slots and signals to link with our UI.<br />In our example, the QML code binds the display property from the model into a text element that we call Display.<br />Javascript is also used to map the buttons in the layout with the actions that must be performed, calling the methods which the CalculatorEngine exports to QML.
<br /><code><br />// delegates of each model's item will be created<br />// to fill the grid view<br />delegate: Component {<br /> Item {<br /> width: grid.cellWidth<br /> height: grid.cellHeight<br /> Button {<br /> anchors.fill: parent<br /> anchors.margins: 3<br /> icon: modelData.source<br /> onClicked: {<br /> // we are using javascript to map the buttons<br /> // with the actions it must perform<br /> var currentItem = Calc.landscapeButtonsModel[index];<br /> var action = currentItem['action'];<br /> action();<br /> }<br /> }<br /> }<br />}<br /></code>
<br />h3. Using the Qt Resource System
<br />Qt provides a platform-independent resource system, useful to store important files needed by the application. It is a good option to guarantee the deployment and to avoid problems due to the corruption of one of these files.<br />The Qt Resource System can generate a binary containing the files, then the application loads the content from this binary. Another possibility is to embed this generated resource file into the application binary. In this example, we use the second option to embed the images and QML files - check calculator.qrc. For more details regarding can be found in the &quot;Qt Resource System documentation&amp;quot;:http://doc.qt.nokia.com/4.7//resources.html


* The UID3 is an unique value that identifies your application. By default QtCreator will set a temporary <span class="caps">UID</span> which is just useful for development purpose. However, in order to submit your application to <span class="caps">OVI</span> store, you will need to get a [[http:www.forum.nokia.comDistributePackaging and signing.xhtml|valid <span class="caps">UID</span>]].
<br />h3. Deploying to Mobile using Nokia Qt SDK
<br />h4. Creating a new Mobile Application
<br />While creating a new application you will be prompted to choose what kind of application you are about to create. Choose Qt Quick application:
<br />[[Image:http://developer.qt.nokia.com/uploads/image_upload/b1.png|http://developer.qt.nokia.com/uploads/image_upload/b1.png]]
<br />Continue with the Wizard and choose what targets your application will have. If you want to deploy for Symbian and Maemo click in the respective checkbox.
<br />[[Image:http://developer.qt.nokia.com/uploads/image_upload/b3.png|http://developer.qt.nokia.com/uploads/image_upload/b3.png]]
<br />In application options you can change some target variables. You can set at this time the icon your application will use in Symbian and Maemo platforms and also change the UID3 for Symbian.
<br />''' The UID3 is an unique value that identifies your application. By default QtCreator will set a temporary UID which is just useful for development purpose. However, in order to submit your application to OVI store, you will need to get a [[http://www.forum.nokia.com/Distribute/Packaging_and_signing.xhtml|valid UID]].


[[Image:b5.png]]
[[Image:http://developer.qt.nokia.com/uploads/image_upload/b5.png|http://developer.qt.nokia.com/uploads/image_upload/b5.png]]


====Testing and Deploying====
==== Testing and Deploying ====


After creating the project you can select the desired target in the left panel. In the case below, a Symbian Device is selected.<br /> Note that in the device picture, there is a green circle indicating the device has been detected. QtCreator automatically detects new devices connected in the <span class="caps">USB</span> ports.
After creating the project you can select the desired target in the left panel. In the case below, a Symbian Device is selected.<br />Note that in the device picture, there is a green circle indicating the device has been detected. QtCreator automatically detects new devices connected in the USB ports.


* Note: In order for the device to be detected, it must have ‘Nokia Ovi Suite’ option active in the <span class="caps">USB</span> settings and it must have also <span class="caps">TRK</span> installed (Symbian^3 <span class="caps">TRK</span> sis file can be found at &lt;<span class="caps">PATH</span>_TO_SDK&gt;\Symbian\sis\Symbian^3\TRK).
* Note: In order for the device to be detected, it must have 'Nokia Ovi Suite' option active in the USB settings and it must have also TRK installed (Symbian^3 TRK sis file can be found at &lt;PATH_TO_SDK&amp;gt;^3\TRK).


[[Image:b13.png]]
[[Image:http://developer.qt.nokia.com/uploads/image_upload/b13.png|http://developer.qt.nokia.com/uploads/image_upload/b13.png]]


If the device has been detected, you can test your application at any time in the target device, clicking in the green arrow in the left panel. This will build (if necessary) your application, send it to device and launch it.
If the device has been detected, you can test your application at any time in the target device, clicking in the green arrow in the left panel. This will build (if necessary) your application, send it to device and launch it.
Line 300: Line 274:
The output is like the following:
The output is like the following:


[[Image:b16.png]]
[[Image:http://developer.qt.nokia.com/uploads/image_upload/b16.png|http://developer.qt.nokia.com/uploads/image_upload/b16.png]]
 
When you are ready to deploy your application you can click in ‘Deploy All’. This will generate installation files for your target device. Generally the generated files are placed in the build directory. For Symbian, for example, you can send the generated .sis files to your device, so you can install and run it at any time.
 
[[Image:b14.png]]
 
===Categories:===
 
* [[:Category:Developing with Qt|Developing_with_Qt]]
** [[:Category:Developing with Qt::QtMobility|QtMobility]]
* [[:Category:Developing with Qt::Qt Quick|Qt_Quick]]


* [[:Category:HowTo|HowTo]]
When you are ready to deploy your application you can click in 'Deploy All'. This will generate installation files for your target device. Generally the generated files are placed in the build directory. For Symbian, for example, you can send the generated .sis files to your device, so you can install and run it at any time.

Revision as of 09:47, 24 February 2015





[toc align_right="yes&quot; depth="3&quot;]

How to Migrate Your Application from the Desktop to a Mobile Platform

This tutorial originally appeared on "qtlabs.org.br.":http://wiki.qtlabs.org.br/doku.php?id=howto:desktoptomobile and was written by a team of developers from INdT.

Introduction

Developing for mobile devices require that you pay attention to some details, and migrating your destkop application to the mobile world can be hard if you don't use the right tools and framework. Thanks to Qt and QML, this job can be easy and won't demand too much time from the developer.

This tutorial aims at helping the developer that wants to migrate his desktop application to the mobile, giving tips about architectural changes in your application and mobile best practices.

About QML

We will use a desktop application as an example during this tutorial and we will guide you during the migration of this example to a mobile version. We'll use QML, the mark up language for Qt Quick, to build the mobile interface.

QML provides the means for building dynamic, rich and custom user interfaces. It also improves the integration between JavaScript and "Qt's Object system,":http://doc.qt.nokia.com/4.7/metaobjects.html#meta-object-system allowing it to easily integrate with your C++ code.

About Qt Mobility

Qt Mobility is a set of Qt APIs with features that are usually present on mobile devices, specially phones. Besides being APIs that aim the mobile world, they support different backends, making it easy to develop applications for phones in the desktop. This avoid the "round-trips&quot; between developing on desktop and testing on the phone, allowing the application's development to be faster.

Examples of these APIs are: bearer management, contacts, location, multimedia and sytem information. Basically, Qt Mobility will give you access to the phone features and its sensors.

Canvas-based UIs

While developing desktop applications using Qt the developer usually will use "QWidgets,":http://doc.qt.nokia.com/4.7/qwidget.html which are widgets developed with the desktop in mind and that will look exactly like the "native&quot; widgets of the platform. This also works for the mobile world but today it is more usual to find UIs that are rich and fluid.

In order to properly have UIs that can be animated and that doesn't look like the platform's widgets, one should use a canvas based UI. Qt provides a canvas for developers called "QGraphicsView&quot;:http://doc.qt.nokia.com/4.7/qgraphicsview.html. One of the many differences between QGraphicsView's interfaces and QWidget's ones is that QWidget depends on the screen resolution and that if the developer chooses to use a canvas he must be aware that most of the common widgets are not yeat available out of the box, but that they can be easily built using pixmaps.

This gives extra freedom to the application's designer as he can create all the elements of the screen and they will look like exactly the way they were designed. It is important to say that QML runs on top of QGraphicsView and that it eases the development of the user interfaces. However it is still possible to make everything in plain C+.
This tutorial will focus in the use of QML and its integration with C, trying to keep all the logic in C+ and just making your UI using QML. This is the easiest path if the developer needs to maintain a mobile version of an application at the same time that he maintains the desktop version.

Considerations about mobile UIs

You need to take special care related to the areas that will be "clickable&quot; in your application when you develop to a mobile device.

The "clickable&quot; areas of your application should be big enough to handle the "average&quot; finger size of someone and also you should not forget that the fingers used to interact with your application may vary depending on the device's orientation (landscape vs portrait).

Be sure to make the areas small enough to not overlap each other. Also avoid the device's corners as they are harder for the user to select. During design time, make sure you question yourself if the user is going to use your application with just one hand for example as this may change the user experience of your application.

Screen Resolution

When developing mobile applications, one thing to keep in mind and take care of is that: If you want your application to run on a wide range of devices, you have to cope with different screen resolutions, that have different properties and features. It is important to allow your application to be scalable to give the user the best experience possible on the specific device. Additionally, many devices support screen rotation when your application is running, so be prepared to dot it.

When writing mobile applications, the developer must avoid using fixed size for items placed on the screen. Qt and QML provide ways to layout items that help you to deal with that. Take a look at the example below.

<br />/* main.qml '''/<br />Item {<br /> width: parent.width<br /> height: parent.height
<br /> Rectangle {<br /> id: rect<br /> width: 100<br /> height: 100<br /> color: &quot;red&amp;quot;
<br /> anchors.centerIn: parent
<br /> MouseArea {<br /> anchors.fill: parent<br /> onClicked: rect.color == &quot;red&amp;quot; ? rect.color = &quot;blue&amp;quot; : rect.color = &quot;red&amp;quot;<br /> }<br /> }<br />}<br />


The example above makes usage of anchors, in order to adapt the application size to screen resolution of the device. Additionally, is important to make your application starts on fullscreen, so the QML item above will anchor at QDeclarativeView, like the example below:


<br />/''' main.cpp '''/<br />QDeclarativeView window;<br />window.showFullScreen();<br />window.setSource(QUrl::fromLocalFile&amp;amp;#40;&quot;main.qml&amp;quot;&amp;#41;);<br />


h2. Memory Management
When dealing with mobile development, the developer must be aware that resources are very limited, e.g. CPU power and memory. So, when porting your desktop application to mobile world, memory management has to be seriously taken into account, since it can become a bottleneck on application execution.
h3. Memory Allocation
There are two ways that a user can allocate memory: Stack allocation and Heap allocation.
Every time a program starts its memory is organized in the following segments:
Text segment: The place where the program code is placed (the machine instructions)
* Stack segment: Reserved block of memory that gets allocated when a thread/function is started, in order to handle local variables and parameters
* Heap segment: Memory block that is reserved for dynamic allocation during the program execution

Heap

The Heap segment is a big block of free memory where user can allocate portions of memory dynamically. For instance, in C a user can allocate memory in the heap using the malloc operator, however in C++ you use the new operator to allocate memory in the heap. The precise location of the requested memory is not known in advance, so those dynamic allocator operators return a pointer to user, in order to manage the allocated memory. Additionally, it is worth telling that continuous block of memory requested does not assure that a sequential block of memory is going to be allocated, this is due to memory fragmentation resulted by various memory allocation and deallocation operations.

Stack

Whenever a thread is started, a block of memory is allocated and given to it, in order to store its local variables and parameters. So, for instance when a C program starts (the main thread) it receives a block of memory, the Stack. When a function is called, a block of memory of this stack (on top of it) is reserved for that function to store its data and gets pushed on the Stack.

Example

<br />int main(int argc, char** argv)<br />{<br /> int a; // allocated on stack

int b[10]; //allocated on the stack

int '''p = (int''') malloc(sizeof(int)); // allocated on the heap

return 0;<br />}<br />

In the example above variable //*a// and //b// (the whole array) get allocated on the stack. On the other hand, //p// gets dynamically allocated on the heap.
When the thread/function exits, all the memory that was being used by it (local variables, parameters, etc…) gets automatically deallocated whereas all memory that was dynamically allocated must be explicitly deallocated by the user, or leaks of memory may appear.
So, the code above would be better written like this:


<br />int main(int argc, char'''* argv)<br />{<br /> int a; // allocated on stack

int b[10]; // allocated on stack

int '''p = (int''') malloc(sizeof(int)); // allocated on the heap

free(p); // free memory on heap

return 0;<br />}<br />

Heap Allocation vs Stack Allocation

Memory allocation on the stack is faster when compared to the heap.

When a memory block is requested to the heap, by new or malloc for instance, the dynamic memory operator starts seeking for an available amount of memory that fits the requested size. On the other hand, the stack size needed for a function is known beforehand. When the function is called a piece of the stack is reserved for the function and then all local variables and parameters are placed there. Additionally, the memory of the stack tends to be used very frequently, due to several function calls, thus it tends to be mapped to the processor's cache, increasing cache hit ratio, which makes the access time shorter than the time spent to access some memory allocated at the heap, which you have higher probability to get a page fault.

Thus, it is preferable to use stack allocation as much as possible when developing something mobile. However, beware that the stack has limited size depending on the platform (Symbian for instance have 8KB by default). Although the stack can be extended, allocating huge amount of memory on stack can cause a stack overflow and makes your program crash. To put in a nutshell, the developer must use memory allocation wisely, balancing between stack and heap, in order to make an fast application.

Note on Symbian Platform

On Symbian you can explicitly set the size of both Stack and Heap sizes. This is done by using EPOCSTACKSIZE and EPOCHEAPSIZE statements at the .mmp file, or put on your .pro file of your Qt application, as described on the example below:

<br />/* app.pro '''/<br />QT ''= core gui network
<br />TARGET = myapp<br />TEMPLATE = app

<br />SOURCES''= main.cpp
<br />symbian {<br /> TARGET.UID3 = 0xeb22583b
<br /> TARGET.EPOCSTACKSIZE = 0x14000 # Stack will have 80kB<br /> TARGET.EPOCHEAPSIZE = 0x020000 0x800000 # Heap minimum of 128kB and maximum of 8MB<br />}<br />


h3. Call by Value vs Call by Reference
Since mobile resources (CPU and memory) are very limited, unnecessary memory copies must be avoided by the developer. One important point to avoid such copies is to watch the way you pass parameters when calling functions. Calling functions by value makes a temporary copy of the object, that is being passed as parameter, in memory. This can take unnecessary space in memory and waste CPU cycles to create a copy of the object, when the same function call could be made by reference, saving that used memory. Thus, if a function call could be done by "call by reference&quot; it is preferable to do it, in order to avoid unnecessary memory copy operations. C++ support call by reference by adding the & operator to the parameters' description of the function. C does not support call by reference, even when you create a function that receives a pointer that pointer is copied in memory, which is a great way to "simulate&quot; call by reference in C.
Below are some examples:


<br />class MyObject<br />{<br />public:
<br /> int i;<br />};
<br />struct myStruct {<br /> int i;<br />};
<br />void add(struct myStruct''' s)<br />{<br /> s-&gt;i+'';<br />}
<br />void add(MyObject &amp;obj)<br />{<br /> obj.i;<br />}
<br />int main(int argc, char** argv)<br />{<br /> MyObject o;<br /> o.i = 10;<br /> add(o); // called by reference
<br /> struct myStruct '''my = (struct myStruct''') malloc(sizeof(struct myStruct));<br /> add(my); // pointer &quot;my&amp;quot; is copied to the function add
<br /> return 0;<br />}<br />


h2. Screen Orientation
Screen orientation is not supported before Qt 4.7.2. So some platform specific code is necessary to lock or unlock the device orientation if you are compiling with old versions of Qt. However, if you are using QtCreator to develop your applications, you don't need to worry about it, since it abstracts all the necessary code in a helper class.
h3. Qt Creator Wizard
While creating a new project, you will be prompted to choose what kind of orientation behavior your application will have. The default option is "Automatically Rotate Orientation&quot;. If your application is designed to work in just one screen orientation, you can choose one of the other options, which are "Lock to Landscape Orientation&quot; and "Lock to Portrait Orientation&quot;.
http://developer.qt.nokia.com/uploads/image_upload/b4.png
h3. Platform-Specific Code
If you need to use platform specific code to set the device orientation, you will need to add some ifdefs in your code. You can follow QtCreator approach extending a QWidget class and adding an extra method to abstract orientation changes. For example, to handle screen orientation for Symbian and Maemo devices you can create a helper class like the following:


<br />// …
<br />#ifdef Q_OS_SYMBIAN<br />#include &lt;eikenv.h&amp;gt;<br />#include &lt;aknappui.h&amp;gt;<br />#endif
<br />ApplicationView::ApplicationView(QWidget *parent)<br /> : QDeclarativeView(parent)<br />{
<br />}
<br />void ApplicationView::setOrientation(ScreenOrientation orientation)<br />{<br />#if defined(Q_OS_SYMBIAN)<br /> if (orientation == ScreenOrientationAuto)<br /> return;
<br /> CAknAppUiBase::TAppUiOrientation uiOrientation;
<br /> if (orientation == ScreenOrientationLockPortrait)<br /> uiOrientation = CAknAppUi::EAppUiOrientationPortrait;<br /> else<br /> uiOrientation = CAknAppUi::EAppUiOrientationLandscape;
<br /> CAknAppUi '''ui = dynamic_cast&amp;lt;CAknAppUi'''&gt;(CEikonEnv::Static()<s>&gt;AppUi());<br /> TRAPD (error, if (ui) ui</s>&gt;SetOrientationL(uiOrientation); );
<br /> Q_UNUSED(error);<br />#elif defined(Q_WS_MAEMO_5)<br /> switch (orientation) {<br /> case ScreenOrientationLockPortrait:<br /> setAttribute(Qt::WA_Maemo5PortraitOrientation, true);<br /> break;<br /> case ScreenOrientationLockLandscape:<br /> setAttribute(Qt::WA_Maemo5LandscapeOrientation, true);<br /> break;<br /> default:<br /> setAttribute(Qt::WA_Maemo5AutoOrientation, true);<br /> break;<br /> }<br />#else<br /> Q_UNUSED(orientation);<br />#endif<br />}<br />


h3. Setting Orientation in Qt 4.7.2
Some new attributes were added in Qt 4.7.2 to set screen orientation. They are as follows:
* Qt::WA_LockPortraitOrientation: //Locks the widget to a portrait orientation, ignoring changes to the display's orientation with respect to the user//
* Qt::WA_LockLandscapeOrientation: //Locks the widget to a landscape orientation, ignoring changes to the display's orientation with respect to the user//
* Qt::WA_AutoOrientation: //Causes the widget to change orientation whenever the display changes orientation with respect to the user//
Usage example: In order to lock screen orientation in portrait mode you can do as follows:


<br />QDeclarativeView view;
<br />view.setAttribute(Qt::WA_LockPortraitOrientation);<br />


Important note: Currently these attributes are being used just for Symbian, but probably this will change in future releases to handle Maemo and other platforms as well
h2. Qt Mobility APIs
As said previously, on Introduction, Qt Mobility is a set of Qt APIs that allow developers to write applications that uses some mobile features (e.g. contacts, location and message service) easily and in a cross-platform way, which means that you only need to have Qt and Qt Mobility frameworks installed on your mobile device.
With these APIs the developers can write applications that:
* Are able to use location services provided by the mobile device, e.g. GPS.
* Can send SMS to other mobile device
* Can play musics/videos and manage multimedia content
* Are able to manage the mobile device contacts
In order to use the Qt Mobility, the developer must use the Qt Mobility namespace on his project.
Ex.:


<br />#include &lt;QtGui/QMainWindow&amp;gt;<br />#include &lt;QTextEdit&amp;gt;<br />#include &lt;QTimer&amp;gt;<br />#include &lt;qgeopositioninfosource.h&amp;gt;<br />#include &lt;qgeosatelliteinfosource.h&amp;gt;<br />#include &lt;qmessagemanager.h&amp;gt;<br />#include &lt;qmessageservice.h&amp;gt;
<br />QTM_USE_NAMESPACE // Qt Mobility namespace
<br />class MainApp : public QMainWindow<br />{<br /> Q_OBJECT
<br />.<br />.<br />


Here are some Qt Mobility APIs
h3. Service Framework
Implement and find services that are available on the mobile device and perform some operations with them.
h3. Messaging
This API gives the user capabilities to handle SMS, MMS, e-mail and any other kind of "messages&quot; the mobile device can deal with.
User can send, search and sort messages, get notified when new messages arrive, compose messages, etc.
h3. Bearer Management
Manages the connectivity state of the mobile device to the network, this includes WLAN and 3G networks
h3. Contacts
Manages all contact information on the mobile device or remotely. With it, user can create, delete and edit contacts
h3. Location
Perform location based operations, like: Retrieve your current GPS location
h3. Multimedia
Manages multimedia content on the mobile device. User can play music and videos, record audio and manage FM radio, for instance.
h3. System Information
Retrieve some system information like Installed Softwares' Version, Features (hardware), Network Status, Display Information, Storage Information, Device Information (battery, profile, SIM card)
h3. Sensors
An API for accessing hardware sensors, like the accelerometer
h3. Camera
Control the camera, capturing images, videos, etc.
When writing an application that uses any Qt Mobility API, the developer must add the respective //*domain*// to MOBILITY variable on the project's .pro file and add the "mobility&quot; option to CONFIG variable.
Below is a table that lists the Qt Mobility domains and associate it with the respective value that must be added to the MOBILITY variable.
|Domain|Value|
|<. Bearer Management|<. bearer|
|<. Contacts|<. contacts|
|<. Location|<. location|
|<. Multimedia|<. multimedia|
|<. Messaging|<. messaging|
|<. Publish And Subscribe|<. publishsubscribe|
|<. Service Framework|<. serviceframework|
|<. Sensors|<. sensors|
|<. System Information|<. systeminfo|
|<. Versit|<. versit|
|<. Document Gallery|<. gallery|
|<. Organizer|<. organizer|
|<. Tactile Feedback|<. feedback|


For instance, if you want to write an application that uses Qt Mobility to send messages to some contact, stored on your device, your .pro would look like this:


<br />/* app.pro '''/<br />QT ''= core gui network
<br />TARGET = myapp<br />TEMPLATE = app
<br />SOURCES''= main.cpp
<br />CONFIG ''= mobility # mobility option in CONFIG<br />MOBILITY''= messaging # domains used on application<br /> contacts<br />


h3. Note on Symbian Platform
When developing for Symbian with Qt Mobility, you have to add the required capabilities that are required by the specified domains (for further information, take a look "here&quot;:http://wiki.forum.nokia.com/index.php/Capabilities).
So, for Symbian the .pro would look like this:


<br />/''' app.pro */<br />QT''= core gui network

TARGET = myapp<br />TEMPLATE = app

SOURCES ''= main.cpp
<br />CONFIG''= mobility # mobility option in CONFIG<br />MOBILITY ''= messaging # domains used on application<br /> contacts
<br />symbian: {<br /> TARGET.CAPABILITY = ReadUserData # Symbian capabilities<br /> WriteUserData  NetworkServices<br />}<br />


h2. Porting a Desktop Application to Mobile
Let's pick one of the Qt examples to guide our study: the "calculator&quot;:http://doc.qt.nokia.com/4.7/widgets-calculator.html
This example uses QWidgets to build a typical desktop interface. Besides that, the code has the logic strongly coupled to the UI definition, what is not the ideal scenario for porting an application to a different screen size and requires some modifications in the original code.
h3. UI and Reusable Logic
Let's take a look at Calculator, the main class in this example:


<br />class Calculator : public QDialog<br />{<br /> Q_OBJECT
<br />public:<br /> Calculator(QWidget *parent = 0);
<br />private slots:<br /> void digitClicked();<br /> void unaryOperatorClicked();<br /> void additiveOperatorClicked();<br /> void multiplicativeOperatorClicked();<br /> void equalClicked();<br /> void pointClicked();<br /> void changeSignClicked();<br /> void backspaceClicked();<br /> void clear();<br /> void clearAll();<br /> void clearMemory();<br /> void readMemory();<br /> void setMemory();<br /> void addToMemory();
<br />private:<br /> Button *createButton(const QString &amp;text, const char *member);<br /> void abortOperation();<br /> bool calculate(double rightOperand, const QString &amp;pendingOperator);
<br /> double sumInMemory;<br /> double sumSoFar;<br /> double factorSoFar;<br /> QString pendingAdditiveOperator;<br /> QString pendingMultiplicativeOperator;<br /> bool waitingForOperand;
<br /> QLineEdit *display;
<br /> enum { NumDigitButtons = 10 };<br /> Button *digitButtons[NumDigitButtons];<br />};<br />


The Calculator class inherits "QDialog,":http://doc.qt.nokia.com/4.7/qdialog.html contains the calculator buttons and display. It also contains several slots responsible for processing the inputs and calculating the results.
With such scenario, our first task is to separate the UI from the logic.
To make things clearer for the sequence of this tutorial, we simplified a bit the original code of this example. Instead of using the createButton() method, we preferred to make all the creation and connections explicit.
We are going to create a new class for the calculator logic. Let's call it //CalculatorEngine//.
This class will receive the slots that were in the Calculator class and will provide a signal emitted everytime a new result is available. This is the interface used by the current QWidget UI and also for the new QML based UI.


<br />class CalculatorEngine : public QObject<br />{<br /> Q_OBJECT
<br /> Q_PROPERTY(QString display READ getDisplay NOTIFY displayChanged)
<br />public:<br /> CalculatorEngine(QObject *parent = 0);
<br />public slots:<br /> void digitAdded(int digitValue);
<br /> void addition();<br /> void subtraction();<br /> void multiplication();<br /> void division();
<br /> void square();<br /> void power();<br /> void reciprocal();
<br /> void equal();<br /> void point();<br /> void changeSign();<br /> void backspace();<br /> void clear();<br /> void clearAll();<br /> void clearMemory();<br /> void readMemory();<br /> void setMemory();<br /> void addToMemory();<br /> void abortOperation();<br /> bool calculate(double rightOperand, const QString &amp;pendingOperator);<br />signals:<br /> void displayChanged(QString text);
<br />private:<br /> void additiveOperation(QString selectedOperator);<br /> void multiplicativeOperation(QString selectedOperator);<br /> void unaryOperation(QString selectedOperator);
<br /> QString display;<br /> double sumInMemory;<br /> double sumSoFar;<br /> double factorSoFar;<br /> QString pendingAdditiveOperator;<br /> QString pendingMultiplicativeOperator;<br /> bool waitingForOperand;<br />};<br />


QML code can invoke slots and Q_INVOKABLE methods declared in C+. It is well described in "this section&quot;:http://doc.qt.nokia.com/4.7-snapshot/qtbinding.html#embedding-c-objects-into-qml-components of the Qt documentation.

Our new Calculator class without all the logic part looks like this:

<br />class Calculator : public QDialog<br />{<br />public:<br /> Calculator(QWidget *parent = 0);

private:<br /> QLineEdit *display;

enum { NumDigitButtons = 10 };<br /> Button *digitButtons[NumDigitButtons];

CalculatorEngine *engine;<br />};<br />

Now Calculator contains the visual elements: 10 Buttons (which inherits "QToolButton&quot;:http://doc.qt.nokia.com/4.7/qtoolbutton.html) and a "QLineEdit.":http://doc.qt.nokia.com/4.7/qlineedit.html The class implementation now concentrates in the creation and layout of the UI. All the logic was moved to <code&gt;CalculatorEngine&lt;/code&gt;, which inherits QObject and has the slots used by Calculator to connect its signals.

With the original code refactored, we have two clearly separated parts of the application: the current desktop UI and the internal logic. The logic part will be reused in the mobile version of the application.

Reusing Existing Models from standard Qt in QML

If your application has a proper separation between the UI and it's logic the transition should not be hard and the UI will be the unique code rewritten. To port your app to QML there are two basic steps to do.

The first one is to create a "QDeclarativeView&quot;:http://doc.qt.nokia.com/4.7/qdeclarativeview.html and make it load the root QML element of your application. The second is to export your current application logic to let QML use it.

The following snippet loads the Calculator.qml element and makes our <code&gt;CalculatorEngine&lt;/code&gt; visible to QML through the id <code&gt;calcEngine&lt;/code&gt;.

<br />int main(int argc, char *argv[])<br />{<br /> QApplication app(argc, argv);

CalculatorEngine calcEngine;<br /> QDeclarativeView view;<br /> QDeclarativeContext '''context = view.rootContext();<br /> context-&gt;setContextProperty(&quot;calcEngine&amp;quot;, &amp;calcEngine); // Exporting logic part of our application to QML<br /> view.setSource(QUrl(&quot;:Calculator.qml&amp;quot;)); // Set the QML file that is inside a Qt Resource file<br /> view.show();
<br /> return app.exec&amp;amp;#40;&amp;#41;;<br />}<br />


Now that we have a CalculatorEngine object visible in QML context we must use its properties, slots and signals to link with our UI.
In our example, the QML code binds the display property from the model into a text element that we call Display.
Javascript is also used to map the buttons in the layout with the actions that must be performed, calling the methods which the CalculatorEngine exports to QML.


<br />// delegates of each model's item will be created<br />// to fill the grid view<br />delegate: Component {<br /> Item {<br /> width: grid.cellWidth<br /> height: grid.cellHeight<br /> Button {<br /> anchors.fill: parent<br /> anchors.margins: 3<br /> icon: modelData.source<br /> onClicked: {<br /> // we are using javascript to map the buttons<br /> // with the actions it must perform<br /> var currentItem = Calc.landscapeButtonsModel[index];<br /> var action = currentItem['action'];<br /> action();<br /> }<br /> }<br /> }<br />}<br />


h3. Using the Qt Resource System
Qt provides a platform-independent resource system, useful to store important files needed by the application. It is a good option to guarantee the deployment and to avoid problems due to the corruption of one of these files.
The Qt Resource System can generate a binary containing the files, then the application loads the content from this binary. Another possibility is to embed this generated resource file into the application binary. In this example, we use the second option to embed the images and QML files - check calculator.qrc. For more details regarding can be found in the "Qt Resource System documentation&quot;:http://doc.qt.nokia.com/4.7//resources.html


h3. Deploying to Mobile using Nokia Qt SDK
h4. Creating a new Mobile Application
While creating a new application you will be prompted to choose what kind of application you are about to create. Choose Qt Quick application:
http://developer.qt.nokia.com/uploads/image_upload/b1.png
Continue with the Wizard and choose what targets your application will have. If you want to deploy for Symbian and Maemo click in the respective checkbox.
http://developer.qt.nokia.com/uploads/image_upload/b3.png
In application options you can change some target variables. You can set at this time the icon your application will use in Symbian and Maemo platforms and also change the UID3 for Symbian.
The UID3 is an unique value that identifies your application. By default QtCreator will set a temporary UID which is just useful for development purpose. However, in order to submit your application to OVI store, you will need to get a [UID].

http://developer.qt.nokia.com/uploads/image_upload/b5.png

Testing and Deploying

After creating the project you can select the desired target in the left panel. In the case below, a Symbian Device is selected.
Note that in the device picture, there is a green circle indicating the device has been detected. QtCreator automatically detects new devices connected in the USB ports.

  • Note: In order for the device to be detected, it must have 'Nokia Ovi Suite' option active in the USB settings and it must have also TRK installed (Symbian^3 TRK sis file can be found at <PATH_TO_SDK&gt;^3\TRK).

http://developer.qt.nokia.com/uploads/image_upload/b13.png

If the device has been detected, you can test your application at any time in the target device, clicking in the green arrow in the left panel. This will build (if necessary) your application, send it to device and launch it.

  • Note: You can also debug your application in the device clicking in the green arrow below the first one (the arrow with a bug).

The output is like the following:

http://developer.qt.nokia.com/uploads/image_upload/b16.png

When you are ready to deploy your application you can click in 'Deploy All'. This will generate installation files for your target device. Generally the generated files are placed in the build directory. For Symbian, for example, you can send the generated .sis files to your device, so you can install and run it at any time.