How to make modern Mobile applications with Qt Quick components

Qt Creator with Components

What Ui toolkit I should use for mobile
application development has been a top issue since Maemo5/Fremantle SDK
alpha release. There were two choices available, GTK+/Hindon and Qt.
The amount of choices has been increased since then and caused a lot
of confusion among developers.

Many developers would like to continue
to use their old familiar UI toolkit, GTK+/Hildon, QWidgets or
Symbian Avkon but there is many reasons reconsider your choice and
look at a new toolkit Qt Quick and Qt Quick Components.

To find reasons, we should look 30
years back into history. The modern desktop Graphical User Interface story
begins from Xerox Palo Alto Research Center, PARC. Most of basic
inventions like mouse, desktop metaphor and windowing system with
overlapping windows were made there. Modern Desktop GUI matured to
it’s current state with first Apple Macintosh release 1984. You can
read more about the history from
http://en.wikipedia.org/wiki/History_of_the_graphical_user_interface
.

After these days, there were no major
changes in Desktop GUI paradigm, we had standard UI elements like overlapping
windows, pull down menus, scrollbars, dialogs, buttons etc all same
form that they are today. There were multiple toolkits with lot of
different APIs implementing the same elements. We had Mac and Windows
native toolkits and several toolkit variants for Linux/Unix. Qt
toolkit, first version released 0.90 was released 1995, offered
common cross platform QWidget API for GUI programming.

There was a major UI paradigm shift in
2007 when the first iPhone was released. The old desktop metaphor with
mouse interaction was abandoned and a new one introduced. Scrollbars,
overlapping windows and mouse-sized UI elements were gone and
replaced with sliding windows, scrolling from content pane and
widgets designed to be used with finger. iPhone was the first successful
touch screen device that was sold with high volumes. Before that,
there were numerous touch screen devices on the market, both pocket sized
and laptop or pad form factor but none were successful.

All these old generation touch screen
devices were still using old desktop UI paradigm and touch screen was
just a mouse replacement. In most of the cases it needed to be used with
a stylus to provide mouse-like pixel accurate pointer. The idea was good
but users just did not like it.

N900 with Maemo5, announced 2009, was
the first Nokia device with a new finger based UI paradigm. Maemo5 had
finger optimized UI components, sliding stacked windows, kinetic
scroll from content pane, all implemented top of desktop-oriented
toolkits, GTK+/Hildon and Qt/QWidgets. The new Mobile UI needed a lot of
modifications to these toolkits that did not become adopted upstreams
implementations as those were still focusing solely on the desktop. Maemo5
implementation was also based on support from tailored window manager
for window transitions and stacked windows, enhanced X11 keyboard
protocol was used for the virtual keyboard. Also, none of these
enhancements were adopted to upstream and Maemo5 toolkit extensions
run only under the Maemo5 environment

Maemo6 that later become MeeGo, was
started from a clean sheet. Enhancing legacy toolkits, GTK+/Hildon or QWidgets, were
insufficient to implement leading edge mobile user experience. The UI
toolkit should be based on QGraphicsView/QGraphicsItem rather than
old QWidgets. The new approach allowed us to take control of UI
elements, transitions and animations inside of the toolkit. Now we had a
possibility for a lot more complex animations in element level, animated
dynamic layouts etc. There were three parallel development paths
inside of Nokia, C++ based Orbit for Symbian, MeeGoTouch for MeeGo
and a totally new concept Qt Quick with QML. For the first MeeGo timeframe
MeeGoTouch was the only available toolkit and it was used for all basic
MeeGo applications.

Qt Quick was part of Qt4.7 released
October 2010. The Qt Quick can be considered revolutionary step in
UI implementation, even complex UIs were possible to implement with a
few easy lines of Qml code. Qml is also easy to learn for UI designers used
to work with web UI tools.

The basic Qt Quick contains only Qml
that could be considered as a low level UI toolkit. It supports basic low
level elements like rectangles, images, mouse areas etc but it did
not contain UI components by itself. If you are using plain QML you need
to implement UI components by yourself. That is not a problem in many
applications that are using their custom UX and UI style but it is
wasting time if you just would like to use system UX with system
style and standard UI elements. The Qt Quick Components project was
introduced to produce ready made Qml UI elements library for Qt
Quick. Current status of components project is pre-alpha for MeeGo
but it still offers basic UI elements and it evolves quickly. Qt
Quick components are also on their way for Symbian and desktop UX.

Our choices

Now we have all pieces together for UI
puzzle and we just need to put them together and make our choice. Many may still think that old toolkits
like GTK+/Hildon and QWidgets look like attractive choices. Nokia
has dropped support of GTK+/Hildon, but QWidgets you’ll find everywhere,
they run on all desktop platforms and they run on major Nokia
platforms. Porting old desktop application with QWidgets looks to most like the 
logical solution, you could use same codebase and cover Linux
desktop, Mac, Windows, Maemo5, MeeGo and Symbian.

Even if the choice looks attractive,
there are two major drawbacks. First of all, if you are porting from
desktop, you need full refactoring of your UI. Desktop metaphor is just
so different than mobile that it just don’t work. This has been
tried and it does not work for multiple reasons starting from screen
size, resolution and UI element sizes that are different. You just don’t
have room for large toolbars, forms etc. and using of tiny UI elements
with finger is impossible.

The second major issue is that mobile
enhancements to these legacy toolkits were not adopted upstream and
they are not cross platform. Even if you find QWidgets in every platform
running Qt, only Maemo5 supports variant that allows implementing
fairly good mobile user experience. In other platforms, you fall back
more or less basic desktop implementation that’s usability in mobile device is very poor. Also due
to differences between the mobile platform implementations and their
behavior, the same code may work in a very unexpected way.

QWidgets

 

 

Choice is clear, Qt Quick

 
Toolkit table

The choice is clear, if you would like make
your application success in Mobile, you should use new UI toolkits
designed to meet the mobile requirements. At the moment there are
three toolkits available, MeeGoTouch, Qt Quick with plain Qml and Qt
Quick Components.

MeeGoTouch is mature but it is not cross platform and not recommended for new
application implementation.

Qt Quick should be considered as the preferred
future way, it is a part of standard Qt4.7 and exists in all platforms
including desktop, Maemo5, MeeGo and Symbian. Qt Quick is clearly the
way that I recommend to developers. Then there is still one question
open, use just plain QML or be early adaptor of Qt Quick components ?

Qt Quick Components

The Qt Quick components project, http://qt.gitorious.org/qt-components,
is currently as pre-alpha in a rapidly evolving phase. It is developed as
MeeGo handset UX as pilot platform but Symbian and desktop UX are on
their way. Even MeeGo components are still early stage, they already
offer fairly good set of MeeGo UI elements and allow implementing
most parts needed of MeeGo handset UX. There are still some UI
elements that are not yet implemented and for the existing ones, APIs are not yet
frozen so you should be prepared to do changes to your QML code when
first released version is published.

MeeGo UX Qt Quick components are currently available ready to use
debian packages for Desktop Ubuntu Lucid and Maveric,
MeeGo/Harmattan ( .deb format) and for Maemo5/N900 as .deb format.
You can start developing applications for MeeGo today, just
by downloading these development libraries. Even if the there will be API
changes before released version, changing some lines of your QML code
is a much smaller task than completely redesigning and reimplementing your UI code once again.

How to start

Following examples are not intended to be comprehensive course or
documentation of Qt Quick components but just a source of inspiration
and also to demonstrate how low the threshold is, even with someone
without any Qt Quick Qml experience, to start coding with the Qt Quick
Components.

Easiest to start development is to install Qt4.7 and Qt Components
to your Desktop Ubuntu from Forum Nokia PPA.

sudo
add-apt-repository ppa:forumnokia/fn-ppa
sudo apt-get update
sudo
apt-get install qt-components-dev libqtm-dev libmeegotouch-dev


You can find more instructions about installing and setting up
Qt4.7 for your Qt Creator from Attila Csipa’s blog
http://qt-funk.blogspot.com/2010/10/fresh-from-oven-qt-extras-for-ubuntu.html

To make your first application with Qt Quick components, you could
use following Qt main program:

#include
<qapplication.h>
#include
<QtComponents/qdeclarativewindow.h>
#include
<qdir.h>

int
main(int argc, char **argv)
{
  QApplication
app(argc, argv);
  QDir::setCurrent(app.applicationDirPath());
  QDeclarativeWindow
window(QUrl::fromLocalFile("main.qml"));
  window.window()->show();
  return
app.exec();
}

Compared to a Qt/QWidget
application, you just should declare
QDeclarativeWindow

and show it. In this first example we don’t try to interface it by
any other way than with our C++ code.

Next
step is UI code with Qt Quick Components. Compared to plain Qt Quick
Qml application, our main element is now Window, not Rectangle and
under window we implement our application UI inside of Page objects.
In the first example we created just an one page but later we add
more of them. Inside of this page we just create one Button component
that is already in our components library and we don’t need to code
it in plain QML. We put couple of Buttons inside of Column just
making easier to add more of them later.

import
Qt 4.7
import com.meego 1.0

Window

{

  id: window
  Component
{
   
id:
mainpageComponent
   
Page
{
    
id:mainPage
    
Column
{
      
anchors.centerIn:
parent
      
spacing:
10
      
Button {

        
height:
50;width: 600
        
text:
"Show a cat"
        
onClicked:(window.nextPage(catComponent))
      
}
      
Button
{
        
height:
50; width: 600
         text:
"Show a dialog"
         onClicked:(window.nextPage(dialogComponent))
      
}
   
}
   }
 
}
  Component.onCompleted:
{
  window.nextPage(mainpageComponent)
 
}
}


To
compile this application, we need also .pro file

TEMPLATE
= app
QT += declarative
LIBS +=-lQtComponents
#
Input
SOURCES += main.cpp
OTHER_FILES
+= \
main.qml

Then
just press “run” from your Qt Creator and this you should see,
you get your application with MeeGo style and all MeeGo window
decorations.

For
real application we need more pages and settings dialog with
scrolling list of option widgets. Current Qt Quick components does
not yet have dialogs that you can populate yourself but in MeeGo many
times sliding pages are already used to implement same function. For
this application i implement two pages one with just Image content
and other being as “settings dialog”.

Settings
dialog, I out content inside of QML Flickable element that implements
surface with kinetic finger scrolling and then Column object for
children component geometry as I did in the main page. I populated this
dialog just for example with Buttons, LineEdit,CheckBox and Switch.

Component
{
  
id: catComponent
  
Page {
    
id:catPage
    
Image {
      
anchors.centerIn: parent
      
source:
"aureo600.jpg"
    
}
  
}
}
Component {
  
id: dialogComponent
  
Page {
    
id:dialog
     Flickable {
      
id: dialogscrolarea
      
anchors.top: parent.top
      
anchors.bottom:
parent.bottom
      
width: parent.width
      
anchors.leftMargin:50;anchors.rightMargin:50
      
contentHeight: dialogcontent.height
      
contentWidth:
parent.width
      
Column {
        
id: dialogcontent
         anchors.left:parent.left;anchors.right:parent.right
        
anchors.leftMargin:50;anchors.rightMargin:50

         spacing:
10
        
Button {
          
text: "Button 1"
          
width:
parent.width
        
}
        
LineEdit {
          
id: line1
          
width:parent.width
          
anchors.left: parent.left; anchors.right:
parent.Right
          
promptText: "Enter text
here"
         }
       
Button {
          
text: "ToggleButton"
          
width:parent.width
          
checkable:true
        }
       
CheckBox {
          
id: cbox
       
}
        Switch
{
          
id: switch1
       
}

Running
this example, you should get the following result. Now you have two
application pages with sliding page transitions and you have dialog
content with kinetic scroll.

This
all is with MeeGo style and MeeGo UX, behaves just as MeeGo
applications should be. If you compare this with QWidgets. In Maemo5
you can implement same function with QWidgets but you don’t have
Switch, in MeeGo Qt you get basic widget style and kinetic scroll but
you don’t have any way to implement sliding stacked windows. Symbian Qt4.7 does not implement kinetic scroll, neither sliding windows nor
multiple windows of any kind.

Maemo
5 and N900

The Forum
Nokia has also released Maemo5 version of Qt Quick Components
package. Thanks to Antonio Aloisio. You can just compile this
example application with Maemo5 PR1.3 Qt4.7 and our qt-components
library from extras-devel and you will get exactly the same looking
application. MeeGo style differs a little bit from Maemo5 native but
even with this small difference, these applications will have
excellent usability on N900. It should not be too big task to hack
code little bit and make variant of components library that has
mostly same style than Maemo5. Only fundamental difference is that
MeeGo applications implement sliding page transition by toolkit,
Mamo5 with Window manager and for that reason, window tittle bar is
here rendered by toolkit, not window manager and that explains
the different look of the home and back button. 

Install
qt-components for your maemo5 scratchbox. You need to have
extras-devel repository /etc/apt/sources.list

deb
http://repository.maemo.org/extras fremantle-1.3 free non-free
deb
http://repository.maemo.org/extras-devel fremantle-1.3 free non-free


At
the moment we have only ARM version, no X86 version because
qt-components depends on libmeegotouch on theme engine and
libmeegotouch is available only as an ARM binary for Maemo5.

[sbox-FREMANTLE-ARMEL:~]>fakeroot
apt-get install qt-components-dev

To
install qt-components to your N900, you need to have extras-devel
repository enabled in application manager and then use the terminal or
ssh:

sudo
gainroot
apt-get install qt-components qt-components-examples

The current
N900 version of qt-components-examples does not yet have desktop files
so you need to run them from the command line. There is also a known bug
that you need to run all components examples with
-graphicssystem
native -option. The current version is developers pre-alpha but I hope
that we can soon deliver a version with desktop files and with these known
bugs fixed.

~
$ /opt/qt-components/gallery/gallery -graphicssystem native

Using
Qt Components from C++

You
may have your application logic made already with C++ and you may be
just considering about implementing a mobile UI. Or you are planning a new
application and you would like it be easilly portable for desktop and
different mobile environments like MeeGo and Symbian. You can
implement all application logic as usual in C++ code and change your
UI layout just loading a  different QML file. You may even implement the
same application binary that can implement handset, tablet and
desktop UX just loading a different QML file. The key element for this is
to make your C++/Qt application interfacing with your QML code.
Signals and slots are the easiest way, you may call slots of your
C++ code directly from the QML code. If you would like to make C++
variables visible to Qml you can do it with
Q_PROPERTY
macro.
The Following example tells more.

The
class itself is just as it was in C++ application, it implements
graphical UI element and for that reason it inherits QgraphicsWidget
and implements paint and boundingRect functions. It has just one slot
for receiving signal from our QML code. No single line of
modifications is needed to the original C++ code. Only change that is
needed is to expose float property called “value” to our QML
code. We need to specify set and get functions value() and
setValue(float) for this variable. The variable is read/write one for
Qml code but if we would like to make our Qml code doing some actions
when this value is changed, we could specify also NOTIFY signal for
it. In our case, this value is only used to change value displayed in
our element so, no notify is needed. That’s all needed to modify your
C++ classes to work with Qt Quick Components UI.

class
GaugeLabel : public QGraphicsWidget
{
  
Q_OBJECT
  
Q_PROPERTY(float value READ value WRITE setValue)
 public slots:
   
void testClicked();
 public:
   
explicit Gauge(QGraphicsItem
*parent = 0);
   
void paint(QPainter *painter,const
QStyleOptionGraphicsItem *option,
QWidget *widget);
   
QRectF boundingRect() const; void
setValue(float val_); float value();
}

To
use our C++ classes from our Qml code, we need add one line to our
example main program, qmlRegisterType.

#include
<qapplication.h>
#include
<QtComponents/qdeclarativewindow.h>
#include
<qdir.h>

int
main(int argc, char **argv)
{
  QApplication
app(argc, argv);
  qmlRegisterType<GaugeLabel>("Efis",
1, 0, "GaugeLabel");
  QDir::setCurrent(app.applicationDirPath());
  QDeclarativeWindow
window(QUrl::fromLocalFile("main.qml"));
  window.window()->show();
  return
app.exec();
}

And
then we can use our class from QML as any QML component, we just need
import it like here as
import
Efis 1.0

. Then in code we just use it as object as any QML native object and
we can spefify it’s size and coordinates. Line
value:valueSlider.value*3 binds value returned Slider component
named valueSlider. Our C++ class setValue(float) is automatically
called every time than we move the slider and value displayed by our
C++ component changes automatically when slider is moved. In Button
component we specify onClicked that calls a slot from our C++ class.

import
Qt 4.7
import Efis 1.0
import com.meego 1.0

Window
{
  
id: window
   Component {
    
id: mainpageComponent
    
Page {
    
id:mainPage
    
GaugeLabel {
     
id: gb
     
x:200;y:200;width:100;height:40
     
value:
valueSlider.value*3
     
gaugeStyle:16
     
name:
"MiuMau"
    }
  Slider
{
    id:valueSlider
   
x:350;y:200
  }
  Button
{
   
id:testButton
   
x:350;y:250;width:160;height:40
   
text:"TestButton"
   
onClicked: { gb.testClicked(); }
  }
 }
 }
 
Component.onCompleted: { window.nextPage(mainpageComponent);
}
}

Final
result looks a like this:

Conclusion

Qt
Quick with Qt Quick Components is the best choice for implementing
new mobile application UI today. Qt Quick Components is at pre-alpha
phase at the moment but it is already usable for starting application
development. We have currently only MeeGo UX supported but it runs on the
desktop, Maemo5 N900 and MeeGo. You can get the latest build done by
Forum Nokia from our PPA and maemo extras-devel repository. When you
start development with current pre-alpha, you can count on that there will be API changes.
Symbian and desktop UX comes later. Interfacing Qt Quick Components
UX to your Qt C++ code is very easy and when all UI is in the QML code,
changing the UX is very easy.

 

Links:

 

http://qt.gitorious.org/qt-components


http://qt-funk.blogspot.com/2010/10/fresh-from-oven-qt-extras-for-ubuntu.html

https://launchpad.net/~forumnokia/+archive/fn-ppa

http://doc.qt.nokia.com/4.7/qtquick.html

 

Leave a Reply