Apps für das Nokia N9 - ein How To für MeeGo Qt/QML Apps

2011-06-23 19:07

Nokia hat ja nun sein erstes MeeGo Handy vorgestellt, das Nokia N9. Es ist nicht das Gerät was man vorher schon unter dem Begriff N9 kannte, dies heisst nun N950. Das N950 jedoch kommt nicht auf den Endkundenmarkt, sondern wird nur exklusiv an Entwickler verteilt oder ausgeliehen von Nokia. Von der Hardware sind beide Geräte fast Identisch, das N950 verfügt aber über eine ausziehbare Tastatur, ähnlich dem E7. Aber als Entwickler steht für mich natürlich die Software im Focus. Und hier wie man am besten nun Apps für das N9 und MeeGo entwickeln kann.

Appentwicklung

Der Standard für die Entwicklung von Apps unter MeeGo ist Qt mit QML. QML empfiehlt sich als Oberflächentechnik, weil man damit sehr viel modernere Oberflächen gestalten kann als mit den Qt Widgets. Ausserdem bietet QML schon von Haus aus vieles, was die UI einer App haben sollte. In meinem letzten Blogbeitrag zu QML und Qt habe ich mich damit beschäftigt, wie man C++/Qt und QML am Besten verbindet, um damit moderne Apps entwickeln zu können. Denn das ist für mich gerade der Vorteil, nämlich dass ich QML und Qt so gut kombinieren kann. Seitdem habe ich eine erste eigene App mit QML und C++ entwickelt, einen Feedreader. In diesem Blogbeitrag möchte ich auch meine Erfahrungen damit wiedergeben.

Die Oberfläche - QML


Wie ich schon erwähnte, denke ich das für Apps QML als Oberflächentechnik sehr gut geeignet ist. Mit dem in Qt 4.8 kommenden Open Scene Graphen sowie den bald erscheinenden QML Components (Steuerelemente für QML), halte ich die Technik sogar für die derzeit beste. QML hat hierbei eine steile Lernkurve. Allerdings ist der Einstieg relativ einfach, weil der Qt Creator heute bereits einen QML Designer besitzt, welcher auch für den Einstieg gut geeignet ist. Trotzdem schreibt man als Programmierer seine Oberflächen lieber von Hand, es ist schneller, und der Designer versteht nicht alles.
Da es aktuell noch keine Components gibt, muss man recht viele Elemente von Hand erstellen, was aber auch den Vorteil hat, das nicht jeder Button überall gleich aussieht, und man so gezwungen ist, sich Gedanken über die Gestaltung eben dieser zu erstellender Elemente zu machen.
Sehr einfach ist die Darstellung von Listen in QML, der ListView lässt sich sehr einfach mit einem Delegate verbinden, welcher die eigentliche Darstellung eines einzelnen Elementes übernimmt. Auch kann man im ListView entsprechende Anfangs und Endelemente anlegen, für Footer oder Header zum Beispiel. Ebenso gibt es weitere Views, wie Grid und TreeView.

Qt & C++ im Backend


Es wird immer wieder betont, das man für QML Apps kein C++ benötigt, und man die Logik auch in Javascript implementieren können. Technisch mag dies richtig sein, praktisch gebe ich aber der Variante mit C++ als Backend die Vorfahrt. Es ist sehr einfach die beiden Welten zu verbinden, die Views in QML lassen sich mit dem bewährten Model-View Prinzip mit Datenfüttern, so kann man entsprechende Modellklassen sehr einfach in Qt realisieren. Benötigt man noch Persistenz kann dies sehr einfach über ein QSqlModel oder QTableModel implementiert werden.
Häufig benötigt man in QML aber auch weitere Infos, welche das Model nicht so enthält, oder erst Berechnet werden müssen. Hier kann man die Performance von C++ nutzen. Eine Einkaufszettel App möchte zum Beispiel die Summe aller Positionen darstellen. Hier könnte man im Model für die Rechnungspositionen nun eine Methode totalSum() anlegen, welche eben dieses in C++ ausrechnet. Um diese Methode aus QML aufrufen zu können, muss man sie mit Q_INVOKABLE im Header kennzeichnen. Danach könnte man dann den Text in QML wie folgt anzeigen lassen:

Text {
    id: txt_rechnungssumme
    text: positionen.totalSum() + " €"
}

Damit kann man schon fast alle Dinge in einer App realisieren. Manchmal gibt es aber auch den Bedarf, das ein QML Element auf ein Signal aus Qt/C++ heraus reagiert. Normalerweise nutzt man hier die Modelklassen, da so die Oberfläche immer schon automatisch ein Update erhält. Es gibt aber Fälle, wo der Aufwand ein eigenes Modell zu implementieren nicht lohnt, oder eben nur ein Signal an QML gesendet werden soll. Hier finden sich in der Dokumentation verschiedene Möglichkeiten, in der Praxis konnte ich vorallem das Connections Element von QML nutzen, andere Möglichkeiten fand ich entweder zu Umständlich, oder funktionierten nicht. Mit dem Connections Element kann man in QML auf ein Signal aus Qt reagieren:

Connections{
        target:  appObj
        onFeedsScanned:{
            console.log("signal received!")
            rect_selfeed.visible= true;
        }
}

Konkret benötigte ich dies um ein Element in QML aufklappen zu lassen, nach dem die Daten dafür eingegangen und verarbeitet waren. Ich würde alle Logik und auch die Netzwerkschicht in C++ und Qt implementieren, auch die Datenbank für Persistenz lässt sich über Qt im Backend sehr gut einbinden. Ebenso ist Qt Mobility in Qt sehr leicht anzusprechen, so das sich Sensordaten wie die aktuelle Position direkt im Backend weiterverarbeiten lassen.
Ebenso lässt sich QML durch C++ leicht erweitern, wenn man zum Beispiel bestimmte Elemente selberzeichnen will, dann geht das über QDeclarativeItem relativ einfach. Man muss lediglich eine Klasse davon ableiten.

Fazit


Mit meinem ersten Qt/QML Projekt habe ich viel gelernt, und einiges an Erfahrung was QML angeht gewonnen. So würde ich zum Beispiel dazu raten, statt width und height eines Objektes lieber dessen anchor Properties zu verwenden. Das zusammenspiel zwischen QML und C++ klappte für mich reibungslos, und sehe ich als eine der großen Stärken dieser Technik an.
Eine andere Erfahrung war, das die Symbian Toolchain nicht so gut mit modernen C++ Libraries wie boost::spirit klarkommt. Meinem im Frühjahr mit spirit erstellten RFC822 Parser konnte ich deshalb nicht nutzen. Ein Ersatz in Qt war zwar schnell programmiert, ist aber längst nicht so flexibel wie die spirit Variante.
Aktuell arbeite ich in einem Projekt mit, bei dem ich sehr viel Erfahrung mit dem Backend hinter QML sammeln kann, hier werden Modelle extensiv genutzt um verschieden Daten mit der QML UI zu teilen. Ebenso kommen die QML Components zum Einsatz, welche noch mal die Entwicklung mit QML vereinfachen. Mit dem erscheinen des N9 werden auch diese QML Components auf MeeGo einsatzbereit sein.


Zurück