Aus Linux-Magazin 04/2011

Mit Qt Mobility in QML und C++ Apps für mobile Geräte entwickeln

© kobra78, Fotolia.com

App-Entwickler möchten möglichst verschiedene Zielplattformen beliefern. Nokia schickt dafür Qt samt der IDE Qt Creator [1] ins Rennen, seit Kurzem ergänzt durch die API-Sammlung Qt Mobility. Damit greifen Entwickler auf Telefonfunktionen zu, etwa auf Kontakte oder Multimedia-Ausgänge (Tabelle 1).


Um C++-Fremden – etwa Designern – den Zugang zur bewegten Welt mobiler Apps zu erleichtern, haben die Entwickler die Qt Metaobject Language (QML) geschaffen: Sie erlaubt es, Anwendungsoberflächen mittels Objekten und Eigenschaften in einem Javascript-Dialekt zu beschreiben. QML bildet zusammen mit anderen Teilen das “Qt UI Creation Kit” (Qt Quick, [2]) und ist Teil von Qt 4.7.

Besser hybrid

Die Autoren dieses Artikels finden: Hybride Apps sind besser als einsprachige Apps. Die Stärken von QML und C++ ergänzen sich zu schicken und performanten Anwendungen. Die Kombination ermöglicht Aktionen, die QML derzeit nicht – oder nicht elegant – implementiert: Die Beispielanwendung in Abbildung 1 schießt in QML über das Multimedia-API von Qt Mobility Fotos und versieht sie in normalem C++ mit einem Zeitstempel.

Abbildung 1: Die Qt Meta Object Language (QML) und das C++-basierte Qt-Framework bandeln mittels der API-Sammlung Qt Mobility mit Smartphone-Funktionen an.

Abbildung 1: Die Qt Meta Object Language (QML) und das C++-basierte Qt-Framework bandeln mittels der API-Sammlung Qt Mobility mit Smartphone-Funktionen an.

Qt Mobility kennt derzeit erst wenige Zielplattformen. Die Preview-Version 1.1 beherrscht die Nokia-Geräte N900 mit Maemo und das N8 mit Symbian 3. Experimentell unterstützt sie die Vorabversion von Meego Netbook für Intel-Atom-Rechner. Die in diesem Artikel entwickelte App zielt auf das N900. Wer nicht im Besitz eines solchen Geräts ist oder die versprochene Zielplattform-Unabhängigkeit austesten will, findet am Ende des Artikels Hinweise für Meego.

Der Entwicklerrechner ist leicht vorbereitet (siehe Kasten “Preview Qt SDK 1.1 installieren”). Bevor es mit dem Programmieren losgeht, sind etliche Schritte zu tun, um ein Rahmenprojekt anzulegen und auf die Endgeräte zu trimmen.

Preview Qt SDK 1.1
installieren
Der Download des Installations-Wizard erfolgt von Nokias Webseiten [3]. Der Wizard ist beispielsweise im Ordner »$HOME/tmp_Downloads/« gut aufgehoben. Für 32-Bit-Linux startet den Wizard dann die Kommandofolge:

cd $HOME/tmp_Downloads/
chmod u+x Qt_SDK_Lin32_online_v1_1_UTP_en.run
./Qt_SDK_Lin32_online_v1_1_TP_en.run

Im Wizard ist bei »Qt SDK Technology Preview Setup« die Lizenzvereinbarung durchzulesen. Nach der Wahl des Installationsverzeichnisses ist sie erneut zu bestätigen, was den Download auslöst. Der Wizard ermittelt die benötigten Dateien, lädt sie vom Server herunter und installiert die verschiedenen Komponenten des SDK auf dem System.

Nach der Meldung »Installation finished!« startet ein Klick auf »Next« und noch einmal »Finish« bereits den Qt Creator und öffnet im voreingestellten HTML-Browser die Readme-Seite, der wichtige Neuerungen zu entnehmen sind. Für die Zielplattform N900 ist ferner die Doku-Seite “Setting Up Development Environment for Maemo” interessant.

Aller Anfang ist Qt

Der im SDK 1.1 enthaltene Creator bringt für die Hybridprogrammierung bereits ein Template mit. Entwickler starten mit dem Button »Create Project …« einen Projekt-Wizard. Der erstellt ein »Qt Quick Project«, also ein QML-Projekt. Von den drei zur Wahl stehenden Projekttypen erlaubt die »Qt Quick Application« den gewünschten Typ hybrider Anwendungen. Nach einem Klick auf »Choose« auf der Folgeseite fällt die Entscheidung für einen Namen und das Verzeichnis des Projekts (im Programmierbeispiel beides »TimePic«).

»Next« bringt den Programmierer zur Ansicht »Qt Versions«, wo er dem Creator das erste Mal die gewünschten Zielplattformen mitteilt. Voreingestellt sind im neuen SDK nur »Desktop» und »Remote Compiler« – für das N900 sind zusätzlich »Qt for Fremantle PR1.3 Devices« und »Simulator Qt for GCC« zu aktivieren. Der »Next«-Button führt ihn zu den »Application Options«, wo die Tab-Seite »Maemo« ein Icon für die App entgegennimmt: Passend legt er eine 64 mal 64 Pixel große PNG-Datei in das Projektverzeichnis. Das SDK paketiert später alle darin gefundenen Dateien und Unterverzeichnisse für den Einsatz auf dem Zielgerät.

Auf der folgenden »QML Sources«-Seite erzeugt die Option »Generate a main.qml file« den Startpunkt. Abschließend erlaubt die »Summary«-Seite die Auswahl eines Versionskontrollsystems – in der Preview-Version des verwendeten SDK sind es Mercury und Git. Mit »Finish« gibt der Qtler die Einstellungen frei: Die Dateien des jungfräulichen Projekts präsentieren sich baumartig im Panel.

Mit dem »Mode Selector« von Qt Creator fügt der App-Entwickler dem Projekt mittels der Auswahl »Projects« wieder die zwei Plattformen hinzu. Dazu benutzt er zweimal das »+«-Symbol, einmal für Maemo, einmal – zu Testzwecken – für den Qt-Simulator. Ein Blick auf die Fläche »Desktop« stellt sicher, dass dort für die Betriebsmodi »Debug« und »Release« jeweils die Qt-Version »Desktop Qt for GCC (SDK)« angewählt ist.

Um die App testen zu können, teilt der Entwickler dem Simulator zuletzt den Pfad zur Bibliothek »libQtMobilitySimulator.so.1« mit. Dafür nutzt er im Bereich »Build Environment« den Dialogeintrag »Details« mit seiner Variablenliste. Mit »Add« fügt er einen neuen Eintrag hinzu, indem er die Variable »LD_LIBRARY_PATH« auf den Wert »SDK-Pfad/Simulator/QtMobility/gcc/lib« setzt.

Zur Belohnung für die umfangreichen Vorbereitungen erfüllt Leben die IDE: Der »Target Selector« unterscheidet Zielplattformen und kennt neben dem Debug- auch den Release-Modus.

Ans Eingemachte: Der Code

Die Methoden der Beispiel-App rufen eine C++-Klasse auf. Die Hilfsklasse bedarf keiner Bildschirmausgabe, daher ist sie kein sichtbares »QDeclarative«-Item: Sie leitet sich schlicht von »QObject« ab.

Tipparbeit erspart dem Programmierer der »Class Wizard« (Abbildung 2), er wählt Dateinamen nach dem Klassennamen, was sich auf Wunsch auch ändern lässt. »Next« führt zur »Summary«-Seite, ein letztes »Finish« erzeugt die Dateien. Im Editor erscheint jetzt die Datei »picturelabeler.cpp«.

Abbildung 2: Der C++-Class-Wizard erzeugt Header und Implementierungsdatei einer neuen Klasse und trägt sie in das Projekt ein.

Abbildung 2: Der C++-Class-Wizard erzeugt Header und Implementierungsdatei einer neuen Klasse und trägt sie in das Projekt ein.

Um die Deklaration anzupassen, erhält die vom Wizard erzeugte Klassendeklaration »picturelabeler.h« im Zweig »Headers« des Projektbaums das Makro »Q_INVOKABLE«, das QML später aufrufen wird. Der Abschnitt »public« sollte jetzt so aussehen:

public:
    explicit PictureLabeler(
        QObject *parent = 0 );
    // returns the timestamp
    // or an empty string on error
    Q_INVOKABLE QString addTimestamp(
        const QString& pictureFilename );

Zurück in der Implementierungsdatei klickt der Qt-Entwickler im Bereich »Open Documents« auf »picturelabeler.cpp« (Listing 1). Nach den Includes am Textbeginn bleibt der Konstruktor leer (Zeile 8). Ab Zeile 13 implementiert er die neue Methode »addTimestamp()«.

Listing 1:
»picturelabeler.cpp«
01 #include <QDateTime>
02 #include <QFont>
03 #include <QImage>
04 #include <QPainter>
05
06 #include "picturelabeler.h"
07 
08 PictureLabeler::PictureLabeler( 
09   QObject *parent) : QObject(parent)
10 {
11 }
12 
13 QString PictureLabeler::addTimestamp(
14   const QString& pictureFilename )
15 {
16   const QString dt =
17     QDateTime::currentDateTime().toString();
18   QImage img( pictureFilename );
19 
20   if( ! img.isNull() ) {
21     QPainter painter( &img );
22     painter.setPen( Qt::blue );
23     painter.setFont(QFont( "Arial", 32 ) );
24     painter.drawText(16,img.height()-18, dt );
25 
26     if( img.save( pictureFilename ) )
27         return dt;
28   }
29   return QString("");
30 }

Um die Klasse QML zur Verfügung zu stellen, muss die »main.cpp« des Projekts ihren Typ bei der QML-Engine registrieren. Dafür erhält sie zu Beginn die zwei benötigten Header und nach Instanzierung der »QApplication« die Template-Methode »qmlRegisterType()«:

#include "picturelabeler.h"
#include <qdeclarative.h>
[...]
  QApplication app(argc, argv);
  qmlRegisterType<PictureLabeler>(
      "com.basyskom.qmlcomponents",
      1, 0, "PictureLabeler" );[...]

Nun darf der QML-Code auf die C++-Hilfsklasse zugreifen. Die App entsteht im Weiteren allein durch Editieren der QML-Hauptdatei.

Das Beispiel spricht Qt Mobility nur von QML aus an, daher benötigt es keine Anpassungen in der Datei »TimePic.pro«. Wer auch von C++ aus auf Qt Mobility zugreifen möchte, beachtet die Hinweise im Kasten “Tipps und Tricks”. Die vollständige QML-Hauptdatei liegt mit allen anderen Sourcen auf dem Listing-Server bereit [2]. Weitere QML-Beispiele sammelt die Doku-Seite zu Qt Quick [3]. Im Folgenden zeigt ein kurzes Codebeispiel die Konzepte, die in der Beispiel-App Anwendung finden.

Tipps und Tricks
Während der Artikel entstand, haben die Autoren eine Reihe Erfahrungen gesammelt. Mögen sie anderen Entwicklern beim Umschiffen derselben Probleme helfen!

Qt Mobility und C++

Wenn die Anwendung von C++ aus auf Qt Mobility zugreifen soll, ist der erste Schritt ein Doppelklick im Projektpanel von Qt Creator auf die betreffende Datei. Würde die Beispielanwendung nicht von QML, sondern von C++ auf das Qt-Mobility-Camera-API zugreifen, so wäre in der ».pro«-Datei das Qt-Mobility-Modul »multimedia« anzumelden, wie es der blau hinterlegte Text in Abbildung 4 zeigt.

Abbildung 4: Wenn der Entwickler statt über QML in C++ auf das Kamera-API zugreifen möchte, fügt er in der Projektdatei des Qt-Build-Tools Qmake die Auswahl des Qt-Mobility-Moduls »multimedia« hinzu. Das Programmierbeispiel wählt stattdessen den Weg über QML.

Abbildung 4: Wenn der Entwickler statt über QML in C++ auf das Kamera-API zugreifen möchte, fügt er in der Projektdatei des Qt-Build-Tools Qmake die Auswahl des Qt-Mobility-Moduls »multimedia« hinzu. Das Programmierbeispiel wählt stattdessen den Weg über QML.

Fehler beim Kopieren auf das Target

Beim Kopieren der App auf das N900 kann es im Output-Fenster des Creator zu Fehlermeldungen kommen, weil ein anderes Programm die Systemdatenbank belegt. Abhilfe schafft, auf dem Gerät alle anderen Programme außer dem Fenster »Developer Passwort« des Mad-Developer zu schließen.

Möglicherweise erscheint im Output-Fenster nun diese Fehlermeldung:

Starting remote process ...
file:///opt/usr/share/TimePic/qml/TimePic/U main.qml:1:1: module "QtQuick" U 
is not installed
     import QtQuick 1.0
     ^
Terminated

Sie bedeutet, dass statt Qt 4.7.1 das schwächere 4.7.0 installiert ist. Falls die Systemintegrität nicht durch ein isoliertes Qt-Update in Gefahr geraten soll, ist eine geänderte erste Zeile in »main.qml« die Alternative: Statt »import QtQuick 1.0« muss sie »import Qt 4.7« lauten.

Möglich ist auch ein ELF-Error beim Ausführen auf dem Gerät. Erscheint beim Run mit Target »Maemo« und »release« die Fehlermeldung »:-1: error: main.o: Relocations in generic ELF (EM: 3)«, so hilft es, mit den Menü-Optionen »Build | Rebuild all« einen neuen Versuch zu starten.

Fehler beim Ausführen der App im Target»Desktop«

Der beim Entstehen des Artikels verwendeten Technology Preview des Qt SDK fehlte das QML-Modul von Qt Mobility für den Desktop. Das führte dazu, dass das QML-Programm beim Befehl »import QtMultimedia-Kit 1.1« unverrichteter Dinge abbrach. Es vermisste offenbar die Datei »QTSDK//Desktop/Qt/471/gcc/lib/libQtMultimediaKit.so.1.0.2«. Ein Suchlauf könnte sich lohnen – eventuell kursieren dazu inzwischen Tipps in Internetforen.

Hallo QML

Das in Listing 2 gezeigte QML-Programm erzeugt der Projekt-Wizard für jede neue Qt-Quick-Anwendung. Der Wizard deklariert per Default im »Hello World«-Hauptelement die »MouseArea« parallel zu einem »Text«-Element. Damit deckt sie die gesamte Fläche des umgebenden Hauptrechtecks ab: Ein Mausklick irgendwo im Fenster schließt die App. Wandert die »MouseArea« aber wie in Listing 3 in die Deklaration des »Text«-Elements, beenden nur Klicks auf den Text die App, sie ignoriert Mausereignisse in der leeren Fläche um den Text herum.

Listing 2: Mausklick im
Hauptfeld
01 Rectangle {
02   width: 360
03   height: 360
04   Text {
05     text: "Hello World"
06     anchors.centerIn: parent
07   }
08   MouseArea {
09     anchors.fill: parent
10     onClicked: {
11       Qt.quit();
12     }
13   }
14 }

Zu sehen war bereits, dass der Entwickler C++-Methoden für QML verfügbar macht, indem er sie in der betreffenden Headerdatei mit dem Makro »Q_INVOKABLE« kennzeichnet. Auch in Listing 3 ruft Zeile 7 eine C++-Funktion auf, um die App zu beenden: »Qt.quit()« schließt die Hauptanwendung einschließlich Viewer mit der laufenden QML-App. Dies funktioniert nur, wenn man im Wizard durch die Wahl des Typs »Qt Quick Application« eine hybride App erzeugt. Eine solche App startet im C++-Hauptprogramm eine »QApplication« und verwendet die Klasse »QmlApplicationViewer«, um den QML-Code zu laden, zu parsen und auszuführen.

Listing 3: Mausklick im
Textfeld
01 Text {
02   text: "Hello World"
03   anchors.centerIn: parent
04   MouseArea {
05     anchors.fill: parent
06     onClicked: {
07       Qt.quit();
08     }
09   }
10 }

Im Folgenden kommt außerdem das Konzept zum Tragen, dass QML-Elemente zumeist rechteckige Bereiche des Programmfensters sind. Als oberste Ebene dient oft das Element »Rectangle«, möglich wären auch andere deklarative Objekte. Die Referenz [4] führt alle QML-Elemente auf. Unsichtbare Elemente wie die »MouseArea« leisten Hilfsdienste: Ebenso wie die sichtbaren Elemente enthalten sie Deklarationen und Steuercode, der meist in kleinen Funktionen steckt (hier die »onClicked()«-Methode). Schließlich stellen Eigenschaften einen Großteil des üblichen QML-Code. Werte für »width« und »text« setzen die in »anchors« zusammengefassten Properties in Bezug zueinander, etwa »fill« oder »centerIn«. Das »Item«-Element dient als Basis aller sichtbaren QML-Elemente, ein Blick in die Dokumentation lohnt [5].

Die hybride Beispiel-App »TimePic« deklariert zu Beginn im Hauptelement zunächst drei Properties vom Typ »int«, um den in QML nicht vorhandenen Aufzählungstyp Enum zu simulieren (Listing 4, Zeilen 1 bis 3). Der symbolische Name »pageModeCommandView« in Zeile 3 ist sicherer, als wenn dort »pageMode = 2« stünde: Mögliche Tippfehler erkennt der QML-Parser bei Namen, nicht jedoch bei Zahlen.

Listing 4: Der
Labeler
01 property int pageModeCommandView: 1;
02 property int pageModeImageView:   2;
03 property int pageMode: pageModeCommandView;
04 [...]
05 PictureLabeler {
06   id: labeler
07 }
08 
09 Camera {
10   id: cameraObject
11   anchors.centerIn: parent
12   width: 100
13   height: 100
14 
15   onImageCaptured: {
16     console.log("Image captured!" )
17   }
18 
19   onImageSaved: {
20     console.log("Image saved!" )
21     imageFilename.color = "blue"
22     imageFilename.text = "images files " + capturedImagePath
23 
24     var stamp = labeler.addTimestamp(capturedImagePath) 

Aus den importierten C++-Modulen instanziert die App als Nächstes die Klassen »PictureLabeler« als »labeler« (Zeile 5) und »Camera« als »cameraObject« (Zeile 9). Der Labeler erhält nur eine ID, das Kamera-Objekt auch Eigenschaften. Das Namensschema der Methoden »onImageCaptured()« und »onImageSaved()« (Zeilen 15 und 19) folgt dem Präfix »on« gefolgt von einem Signal der C++-Klasse, das einen großen Anfangsbuchstaben erhält. Darum verknüpft die QML-Engine die Methode automatisch als Slot mit dem Signal.

Bei Redaktionsschluss dieses Artikels war das QML-Element »Camera« zwar in Qt Mobility 1.1 enthalten, sein API aber noch nicht dokumentiert. Die Sourcen auf Gitorious [6] stellten sich als wertvolle Informationsquellen heraus.

Die Grenze beider Welten

Die Zeile 24 von Listing 4 ist in dreifacher Hinsicht interessant, denn sie schafft den Übergang zwischen den Welten von C++ und QML. Der Anfang »var stamp« instanziert eine Javascript-Variable. Er initialisiert sie mit der eingangs in Listing 1 implementierten Methode »addTimestamp()«. Das Objekt »labeler« stammt aber aus der in Zeile 5 instanzierten Hilfsklasse »PictureLabeler«. Der Parameter »capturedImagePath« ist eine Eigenschaft der Klasse »Camera« aus Zeile 9. Sie ist für QML erreichbar, weil die Headerdatei »QDeclarativeCamera« sie als »Q_PROPERTY« deklariert.

Die Fortführung der »TimePic«-App in Listing 5 beginnt mit dem Quit-Button (Zeilen 1 bis 4). Er ist das erste sichtbare Element innerhalb des obersten QML-Elements »timePicMain«, weil das folgende Rechteck-Element »mainArea« (Zeilen 6 bis 40) seine Unterkante an der Oberkante des Quit-Buttons ausrichten soll (Zeile 9). Die »mainArea« nutzen zwei weitere Rechtecke, »commandView« (Zeilen 11 bis 21) und »imageView« (Zeilen 23 bis 39). Sie erscheinen nie gleichzeitig: Sie würden sich gegenseitig verdecken.

Listing 5: Wechsel der
Programmzustände
01 Rectangle {
02   id: quitButton
03   [...]
04 }
05 
06 Rectangle {
07   id: mainArea
08   [...]
09   anchors.bottom: quitButton.top
10 
11   Rectangle {
12     id: commandView
13     [...]
14     MouseArea {
15       [...]
16       onClicked: {
17        console.log("Capturing a photo with ISO " + cameraObject.iso )
18        cameraObject.captureImage()
19       }
20     }
21   }
22 
23   Rectangle {
24     id: imageView
25     [...]
26     Image {
27       [...]
28       source: cameraObject.capturedImagePath
29     }
30     MouseArea {
31       anchors.fill: parent
32       hoverEnabled: true
33       acceptedButtons: Qt.LeftButton
35       onClicked: {
36         pageMode = pageModeCommandView;
37       }
38     }
39   }
40 }
41 
42 states: [
43   State {
44     name: "StateCommandView";
45     when: timePicMain.pageMode == pageModeCommandView;
46     PropertyChanges { target: commandView; opacity:1 }
47     PropertyChanges { target: imageView; opacity:0 }
48   },
49   State {
50     name: "StateImageView"
51     when: timePicMain.pageMode == pageModeImageView;
52     PropertyChanges { target: commandView; opacity:0 }
53     PropertyChanges { target: imageView; opacity:1 }
54   }
55 ]
56 
57 transitions:  [
58   Transition {
59     from: "StateCommandView"
60     to: "StateImageView"
61     reversible: false
62     SequentialAnimation {
63         NumberAnimation {
64           duration: 100
65           properties: "detailsOpacity,height"
66       }
67     [...]
68     }
69   },
70   Transition {
71     from: "StateImageView"
72     to: "StateCommandView"
73     reversible: false
74     [...]
75   }
76 ]

Wechselnde Zustände

Dieses Muster ist in QML häufig anzutreffen: ein Wechsel zwischen zwei Programmzuständen. Bei aktivem Zustand »StateCommandView« (Zeilen 43 bis 48), schießt die App über die Kamera das Foto, schreibt den Timestamp in die von der Klasse »Camera« gespeicherte Bilddatei und setzt bei Erfolg die Toplevel-Eigenschaft »pageMode« auf »pageModeImageView«.

Der Zustand »StateImageView« hingegen (Zeilen 49 bis 54) lädt über ein Image-Element das gespeicherte Bild in das Rechteck »imageView« (Zeilen 23 bis 40), dessen Name aus der Property »cameraObject.capturedImagePath« stammt. Die »onClicked()«-Methode (Zeilen 35 bis 37) des Mausbereichs dieses Rechtecks setzt den »pageMode« wieder auf »pageModeCommandView« zurück. Dann übernimmt statt des Rechtecks »imageView« wieder das Rechteck »commandView« das Ruder.

Der »States«-Abschnitt der Zeilen 42 bis 55 deklariert beide Zustände. Die »when«-Bedingungen legen fest, wann die QML State Machine den betreffenden Zustand aktiviert. Die Anweisungen »PropertyChanges« ändern die Sichtbarkeit der beiden Rechtecke über die Eigenschaft »opacity«. Genau so, wie der »States«-Abschnitt das Was und Wann der Elemente festlegt, deklariert der Abschnitt »Transitions« das Wie: Er blendet von einer Ansicht zur anderen über. Für weitere Spiele mit animierten Übergängen empfiehlt sich die Animations-Dokumentation [7].

Fertig: Ab ins Testfeld

Der Qt Creator schickt die fertige App zum Simulator, indem der Entwickler ihn im Ziel-Umschalter als aktives Target auswählt. Ein Klick auf »Run« gibt den Startschuss für den Buildvorgang. In der Voreinstellung simuliert der Creator ein N900. Im Erfolgsfall zeigt er im Simulator das Programm ähnlich wie in Abbildung 3 an.

Abbildung 3: Die Beispiel-App »TimePic« legt einen erfolgreichen Testlauf im Simulator hin. Der Testlauf dient auch dazu, Tippfehler im Code oder nicht passende Bibliotheken zu finden.

Abbildung 3: Die Beispiel-App »TimePic« legt einen erfolgreichen Testlauf im Simulator hin. Der Testlauf dient auch dazu, Tippfehler im Code oder nicht passende Bibliotheken zu finden.

Der Simulator kann keine Fotos aufnehmen. Der Testlauf ist dennoch wichtig, etwa um Tippfehler im Code oder nicht passende Bibliotheken bereits vor dem Einsatz auf dem Gerät zu erkennen. Ist der Simulator aktiv, bietet das komplexe Fenster »Qt Simulator Control« vielfältige Möglichkeiten, sein Verhalten zu beeinflussen. Für die ersten Schritte belässt es der Entwickler bei den Voreinstellungen, die die von »TimePic« benutzte rückseitige Kamera simuliert.

Zielgerät N900
vorbereiten
Auf die aktuell verfügbaren Firmware-Updates (PR 1.3 oder neuer) machte der N900-Programm-Manager den N900-Besitzer vermutlich bereits aufmerksam. Falls noch nicht geschehen, verhilft Nokias Howto “How do I use my device to update?” zum erfolgreichen Update [11]. Die aktuelle N900-Firmware-Version haben Qt 4.7 und Qt Mobility bereits an Bord, was die Installation von Meego und das umständliche Booten per Micro-SDHC-Card erspart.

Zentral ist die Installation des Programms Mad-Developer. Er ist im Menü über »App Manager | Download | Development | mad-developer« zu erreichen und erlaubt später eine SSH-Verbindung zwischen Entwicklungsrechner und N900, um die App zu übertragen.

Die Auswahl »Developer Password« zeigt die IP-Adresse und das aktuell gültige SSH-Passwort: Die IP ist standardmäßig 192.168.2.15 (in 255.255.255.0). Sie ändert sich aber auf Wunsch durch Klick auf »Edit | Configure« in der USB-Zeile. Das Passwort ist automatischen Ursprungs und nur so lange gültig, wie der Dialog (Abbildung 5) im Mad-Developer geöffnet ist.

Abbildung 5: Der SSH-Zugriff über das angegebene Passwort ist möglich, solange dieser Dialog geöffnet bleibt.

Abbildung 5: Der SSH-Zugriff über das angegebene Passwort ist möglich, solange dieser Dialog geöffnet bleibt.

Auf dem N900 ist die Verfügbarkeit von Qt Mobility 1.1 sicherzustellen. Gegebenenfalls legt der Entwickler nach, wozu das Paket »rootsh« nötig ist, das die Anmeldung als Superuser erlaubt. In »Programs« ist sodann »X Terminal« zu starten, um ein Konsolenfenster für die manuelle Installation zu erhalten:

sudo gainroot
apt-get install libqtm-11-*

Falls Apt das Paket »libqtm-11-*« nicht findet, schafft ein zusätzliches Repository Abhilfe:

sudo gainroot
echo "deb http://repository.maemo.org/U
extras-devel/ fremantle-1.3 free U non-free" >> /etc/apt/sources.list.d/U hildon-application-manager.list
apt-get update

Nun sollte Apt entweder (als Error) das korrekte Vorhandensein der Qt-Mobility-Bibliotheken melden oder um die Bestätigung zur Installation bitten.

Damit QML die API-Sammlung benutzen kann, sind folgende symbolische Links nötig:

ln -s /opt/qtm11/imports/QtMobility U
  /usr/lib/qt4/imports/QtMobility
ln -s /opt/qtm11/imports/QtMultimediaKit U
  /usr/lib/qt4/imports/QtMultimediaKit

Das Konsolenfenster hat nun seinen Dienst getan, der Dialog des Mad-Developer sollte aber offen bleiben. Ist es bereits zu spät, genügt ein erneutes Anklicken von »Developer Password«, um die SSH-Verbindung mit einem neuen Passwort zu ermöglichen. Die Verbindung zwischen N900 und Entwicklerrechner übernimmt ein USB-Kabel.

Um die App auf echte Geräte zu schicken, sind weitere Schritte nötig: Das N900 braucht ein Firmware-Update und das Programm Mad-Developer (Kasten “Zielgerät N900 vorbereiten”). Das Netbook als Zielgerät bedarf des neuesten Meego und auf Seiten des Entwicklerrechners des Helferleins Mad-Admin (Kasten “Zielgerät Netbook vorbereiten”). Die Meego-Seite [12] listet die von Meego unterstützten Zielgeräte, auf denen die App laufen sollte.

Zielgerät Netbook
vorbereiten
Die Installation von Meego auf dem Netbook [8] unterscheidet sich nicht sehr von der Installation jeder anderen Linux-Distribution [9]. Aber aus dem Meego-SDK [10] benötigt der App-Entwickler zusätzlich MADDE (Meego Application Develop und Debug Environment). MADDE stellt mit dem Mad-Admin ein Tool bereit, das ihn beim Herunterladen und Installieren der so genannten Targets unterstützt. Diese Targets bieten dem Qt Creator eine Toolchain an – genau wie im Fall des N900. Der Creator kann nun mit angepassten Projekteinstellungen im »meego-sdk-creator« das N900-Projekt laden. Der Klick auf »Run« kompiliert die Applikation wie gewohnt, überträgt sie auf das Netbook und startet sie dort.

Vorsicht: Die Qt-Mobility-API-Integration in der Meego-1.1-Netbook-Release (Stand November 2010) ist nicht vollständig abgeschlossen. Bei Schwierigkeiten könnte daher schon ein Update auf die neueste Meego-Trunk-Version oder ein Blick auf das für Frühjahr 2011 angekündigte Meego 1.2 helfen.

Das wahre Leben

Zum N900 führen im Target »Maemo« der Button »Run« und dort der blaue Link »Manage device configurations«. Im erscheinenden »Options«-Dialog schafft der Entwickler per »Add«-Button eine neue Konfiguration, die passenderweise N900 heißen sollte. Den auf »Key« voreingestellten Authentifizierungstyp stellt er auf »Password« um. Die dafür benötigte Zeichenfolge zeigt der auf dem N900 installierte Mad-Developer an. Der »Test«-Button prüft nun die Verbindung – ist alles in Ordnung, hat der Optionendialog ausgedient.

Nahe am Ziel wählt der App-Schöpfer – zurück auf der »Run«-Seite – jetzt im Feld »Deploy to Device« das eben angelegte N900 aus. Im Ziel-Umschalter sucht er sich »Maemo« als aktives Ziel aus, allerdings mit »Release«-Build statt des vorgegebenen »Debug«-Modus. Gespannt klickt er wieder auf »Run«.

Das SDK baut nun ein Maemo-5-Projekt, erzeugt daraus ein Debian-Paket und kopiert es über die SSH-Verbindung auf das N900. Da der Dialog »Developer Password« bei korrekter Vorbereitung auf dem N900 noch geöffnet ist, erlaubt das Gerät SSH-Zugriffe. Nach dem Kopieren installiert das SDK das neue Programmpaket auf dem N900 und startet es.

Herzlichen Glückwunsch! Wer mit der rückseitigen Kamera des N900 nun ein Ziel anvisiert und über die blaue Schaltfläche »Capture Next Photo« ein Bild schießt, sieht in den beiden vormals roten Anzeigezeilen den Namen der erzeugten Bilddatei und den Text des von der C++-Klasse eingetragenen Zeitstempels auftauchen. Das Output-Fenster des Creator freut sich ebenfalls am Erfolg seines Benutzers, wenn die letzten Zeilen Ausgabe ähnlich wie folgt lauten:

Capturing a photo with ISO 0
Image captured!
Image saved!
Image time stamp saved as Fri Jan 14 U 13:58:40 2011
Geschafft: Die erste hybride App ist erfolgreich getestet und installiert. Wer mag, nutzt sie künftig als Basis für eigene Projekte. (ake)

Geschafft: Die erste hybride App ist erfolgreich getestet und installiert. Wer mag, nutzt sie künftig als Basis für eigene Projekte. (ake)

Infos
[1] Tim Schürmann, “Nokias Hausmarke”: Linux-Magazin 10/09, S. 120

[2] Qt Quick: [http://doc.qt.nokia.com/4.7/qtquick.html]

[3] Qt SDK 1.1 Preview:[http://labs.qt.nokia.com/2011/01/20/qt-sdk-1-1-technology-preview-released/]

[4] Referenz QML-Elemente: [http://doc.qt.nokia.com/4.7/qdeclarativeelements.html]

[5] Referenz Item-Elemente: [http://doc.qt.nokia.com/4.7/qml-item.html]

[6] Qt auf Gitorious: [http://qt.gitorious.org/qt-mobility/qt-mobility/blobs/1.1/plugins/declarative/multimedia]

[7] Animationen: [http://doc.qt.nokia.com/4.7/qdeclarativeanimation.html]

[8] Meego für Netbooks: [http://meego.com/downloads/releases/netbook]

[9] Meego-Installationsanleitung:[http://meego.com/devices/netbook/installing-meego-your-netbook]

[10] Meego SDK: [http://wiki.meego.com/SDK/Docs/1.1/Getting_started_with_the_MeeGo_SDK_for_Linux]

[11] N900-Update: [http://europe.nokia.com/support/download-software/device-software-update/faq#faq1]

[12] Meego-Hardware:[http://meego.com/devices/netbook/supported-hardware-platforms]

Die Autoren
Der Diplom-Informatiker Jeremias Bosch arbeitet seit 2009 bei der Darmstädter Basyskom GmbH als Qt Software Consultant. Er koordiniert eine internationale Arbeitsgruppe für Firefox Mobile auf Meego und leitet das Peregrine-Team.

Der Trierer Karl-Heinz Zimmer war Starwriter-Entwickler in der Star Division und Senior Developer in der Klarälvdalens Datakonsult AB. Heute koordiniert er als Senior Qt Consultant der Basyskom GmbH ein Nokia-Forschungsteam.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 7 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben