×
Namespaces

Variants
Actions
Revision as of 18:54, 23 October 2011 by gnuton (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Rotating QWidget based applications on MeeGo Harmattan

From Nokia Developer Wiki
Jump to: navigation, search

This article explains how to make change orientation QtWidget-based application working on on Harmattan...

Article Metadata
Code ExampleTested with
Devices(s): Nokia N9, Nokia N950
Compatibility
Platform(s): MeeGo 1.2 Harmattan
Article
Keywords: QWidget, Orientation
Created: gnuton (11 Nov 2011)
Last edited: gnuton (23 Oct 2011)

Contents

Introduction

Qt is a framework used to develop application software with a graphical user interface (GUI). It allows developers to write the application GUI using QWidget(pure C++), QtComponents(C++/QML/JS) or HTML(C++/HTML/JS).

MeeGo 1.2 Harmattan, the newest Nokia platform in the market, offers to application developers a set of QML Components which can be used to design amazing interfaces where touch input, fluid animations and user experience are crucial. QML Components have been optimized to squeeze out all the GPU power, providing to developers an easy way to code which isn't prone to performance loss as QWidget was. For this reason, Harmattan doesn't really support QWidgets. Porting a Symbian or Maemo QWidget based application to the new platform involves the re-writting of the entire UI. Write a UI with QML is much more easy than with QWidget and the porting doesn't really take so much time. Anyway some developers don't really want to spend time with QML and they want to run the app on MeeGo as it is.

QWidgets on Harmattan limitations

QWidgets on Harmattan suffers of many limitations, where the most important are:

  • No MeeGo Style
  • Application orientation locked in landscape

In this article we will talk about the first limitation and the way how it can be worked around.

Why my QWidget-Based app doesn't rotate on Harmattan?

QWidget class provides a setAttribute method that was largely used on Symbian and Maemo to set the application orientation. A mobile application, in fact could be locked in landscape or potrait, or could even be left free to change orientation according to device orientation, value which is provided by the accelerometer sensor. On Harmattan QWidget::setAttribute(orientation) doesn't work anymore because X11 server has been built without the X Resize, Rotate and Reflect extension called [RandR http://en.wikipedia.org/wiki/RandR], so in few words the screen doesn't rotate anymore; is the application itself which has to rotate. This is an important fact that lets MeeGo to have a fancy and smooth transition effect when an application switches from one orientation mode to another.

How to work around this problem

Missing rotation support on the graphics server forces the application to handle the rotation. But Unfortuantely QWidgets, which have been designed originally for Desktop, are not able to rotate. The only way to rotate a QWidget is to draw it in a canvas and rotate the drawn. As you maybe know, the Qt canvas is called QGraphicsScene. The scene is displayed to the user by a QGraphicsView, and the items in the QGraphicsScene are called QGraphicsItem. To draw a QWidget in a QGraphicsScene, we need a QGraphicsProxyWidget. So if we create a simple application which display as a GraphicsView as main widget and we draw the QMainWindow inside the a GraphicsView we should be able to rotate our app. It seems easy but this is not really the best way, because we should write the code to animate the transition between the two orientation modes and other little things.

So a way better option is to make the graphics item which stores the QWidget, child of a MeeGo Component element.

The solution: "Embedding" a QWidget in a MeeGo Component based application

As it has been said before, MeeGo application uses MeeGo QML components and our goal is to have our application working with different orientation. A MeeGo component application is made by a [Window] and some [Pages]. So to make our application scalable, we will to make the main window of our application child of a Page. For this purpose we have to "transform" our MainWindow widget in QDeclarataiveItem as the code below does.

INSERT CODE HERE

Then the new object is registered and made available to the declarative view

 qmlRegisterType<ProxyWidget>("ProxyWidget", 1, 0, "ProxyWidgetItem");

As said before we could comment the following line since it doesn't really work:

viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
import ProxyWidget 1.0
 
Page { tools: commonTools Label { id: label anchors.centerIn: parent text: qsTr("Hello world!") visible: false } Button{ anchors { horizontalCenter: parent.horizontalCenter top: label.bottom topMargin: 10 } text: qsTr("Click here!") onClicked: label.visible = true } ProxyWidgetItem { anchors.fill: parent }}

Canned Solution

To make your application working in easier I made a template which you could reuse. The instruction to follow in order to use it are [here]. Basically the canned example works in this way. Your application is built as static library and its main widget is loaded by the proxy widget we have seen before.

Limitations

Biggest limitation of this solution are:

  • QTreeWidget::setItemWidget doesn't work as expected: the bug has been reported here
  • If a WebView microfocus doesn't work correctly. The virtual keyboard doesn't disappear when input html element lose the focus: SOLUTION

So far those are the current issue. Please edit this page or leave a comment in case you find new ones. Thanks.


Add categories below. Remove Category:Draft when the page is complete or near complete


==

80 page views in the last 30 days.