Einführung in Qt Quick und QML: Hallo RSS!
Mit Qt Quick und QML steht für mobile Qt-Anwendungen seit 2010 ein deklaratives GUI-Modell zur Verfügung. Deklarativ heißt: man programmiert nicht mehr die Programmabläufe in seine GUI hinein, sondern definiert nur noch, wie sich welches GUI-Element bei welcher Aktion verhalten soll. Der Name Qt Quick (Qt User Interface Creation Kit) steht zunächst als Überbegriff für das deklarative Programmiermodell in Qt. Die dabei verwendete Sprache QML (Qt Meta-Object Language) ist dabei in jeder Hinsicht offen: als Teil des Qt-Frameworks steht sie in einer (L)GPL-Lizenz zur Verfügung und gibt dem Anwender das größtmöglichste Maß an Freiheit bei der Gestaltung seiner Anwendung. Letzteres ist auch gleichzeitig das größte Problem von Qt Quick. Bisher hat sich noch kein einheitliches GUI-Modell etabliert, so dass in nächster Zeit mit einem Wildwuchs an Qt-Quick-Oberflächen zu rechnen ist. Sowohl unter Symbian als auch unter Maemo gibt es keine Vorgaben für die Oberflächengestaltung, nicht einmal Standard-Widgets sind bisher definiert. Es bleibt zu hoffen, dass dieser Missstand mit einem zukünftigen MeeGo-System von Nokia sowie dem Qt-Components-Projekt bald behoben sein wird.
Als ersten Einstiegspunkt soll hier eine Beispielanwendung in reinem QML entwickelt werden. Die Anwendung macht nichts weiter, als die Beiträge des mobileqt.de-Blogs in einer Liste anzuzeigen. Bei Klick auf einen Eintrag der Liste wird die entsprechende Webseite des Beitrags in einem Webview geladen. Wie immer steht der komplette Quellcode des Projekts zum Download zur Verfügung. Der folgende Screenshot zeigt die laufende Anwendung auf dem N900:

Voraussetzung für die Entwicklung ist der aktuelle Release Candidate 2.1 des Qt Creators. Sobald die offizielle Version 2.1 des Qt Creator erschienen ist, sollte das Projekt auch mit dieser Version erstellt werden können.
Quellcode des Projekts
Das gesamte Paket könnt ihr euch auch hier herunterladen. Entpackt einfach das Archiv und öffnet aus dem Ordner halloqml die Datei HalloQml.pro im Qt Creator.
Los geht’s
Zunächst erstellt man mit dem Qt Creator per Datei → Neu ein neues Projekt. Als Projektvorlage wählt man Qt Quick-Projekt und dann Neue Qt Quick-Anwendung. Diese Vorlage erzeugt eigentlich ein Projekt, in dem QML- und C++-Code gemischt wird. Im Gegensatz dazu erzeugt die Vorlage Qt Quick UI ein reines QML-Projekt ohne C++-Anteil. In unserem Fall wollen wir zwar nur in QML entwickeln, der C++-Code erlaubt es uns aber, die Anwendung auf den Portrait-Modus des Mobiltelefons einzuschränken. Praktischerweise erzeugt der Qt Creator ab Version 2.1 diesen C++-Code gleich mit, wie wir nach Erstellung des Projekts gleich sehen werden. Wir wählen also den Projekttyp:

Im zweiten Schritt gibt man dann einfach einen Namen und Pfad für die Anwendung ein:

Nach Klick auf Weiter werden die zu verwendeten Qt-Versionen abgefragt. Hier reichen uns die mobilen Qt-Versionen, also der Simulator und Fremantle-PR-1.3-Geräte (unter Windows auch Symbian):

Der nächste Schritt enthält die Einstellungen für die mobile Anwendung, hier wählen wir gleich für die Ausrichtung die Einstellung Hochformat festlegen, ansonsten belässt man alle Standardwerte:

Die folgenden beiden Schritte können einfach mit den Standardeinstellungen abgeschlossen werden. Nach Klick auf das finale Abschließen ist nun das Anwendungsgerüst erzeugt und der Qt Creator präsentiert die Haupt-QML-Datei main.qml:

Wer möchte, kann sich einmal durch die einzelnen Dateien des Programmgerüsts durchklicken. Die C++-Datei main.cpp enthält beispielsweise den Code zum Laden und Anzeigen der QML-Datei, außerdem wird hier der Portrait-Modus für die Anwendung festgelegt. Die weitere Module des Projekts wie qmljsdebugger-lib dienen ausschließlich zum Debuggen einer Anwendung mit QML-Views und werden vom Qt Creator zur Verfügung gestellt. Uns interessieren diese Dateien im Moment nicht. Für alle weiteren Schritte dieses Artikels editieren wir ab jetzt nur noch die Datei main.qml bzw. später dann noch eine weitere QML-Datei. Zum Ausprobieren können Sie das Projekt gleich einmal im Simulator starten. Ein Klick auf den grünen Play-Button unten rechts reicht dazu aus: “Hello World!” in QML.
Basisarbeit: Ein erster View in QML
Unsere Anwendung wird später aus nur zwei Views bestehen: die Liste der Blogeinträge sowie ein Webkit-View zum Anzeigen der Blog-Webseite. Dazu definieren wir zunächst einmal das Hauptfenster als Rectangle mit den Werten für die Größe des Portrait-Modus unter Symbian (das ist die Mindestgröße; unter Maemo wird die Anwendung automatisch angepasst):
import Qt 4.7
import QtWebKit 1.0
Rectangle {
id: mainScreen
property int currentIndex: 0
width: 360
height: 640
color: "white"
ListView {
id: listviewRss
anchors.fill: parent
focus: true
orientation: ListView.Vertical
}
}
Das Hauptfenster enthält also ein Rechteck der Größe 360×640 und hat die Hintergrundfarbe “white”. Wir definieren außerdem gleich ein property, dass später die ID des aktuell ausgewählten Blogeintrags enthält. Ganz am Anfang binden wir per import QtWebKit 1.0 außerdem das QML-WebKit-Modul ein.
Schließlich definieren wir innerhalb des Rechtecks das erste GUI-Element: einen ListView. In QML schachtelt man zueinander gehörende GUI-Elemente einfach ineinander, wir werden gleich noch eine Reihe weiterer Elemente kennenlernen. Innerhalb des ListView definieren wir per anchors.fill, dass die Liste alle Layout-Angaben von seinem Elternelement (also das Rechteck mainScreen) erben soll. Außerdem erhält die Liste sofort den Fokus für Tastatureingaben und soll schließlich eine vertikale Liste sein. Wo kommt aber nun der Inhalt der Liste her? QML greift hier auf das schon unter Qt verwendete Model-View-Konzept zurück. Während der View für die Darstellung der Liste zuständig ist, liefert das Modell die eigentlichen Daten, in unserem Fall die Einträge eines RSS-Streams.
Die Daten als Modell
QML stellt dem Entwickler drei Modelltypen zur Verfügung. Zusätzliche Modelle können selbst in C++ entwickelt werden. Für unsere Zwecke benötigen wir ein XML-Modell, da die Daten des Blog-RSS in diesem Format gespeichert sind. Glücklicherweise stellt QML genau einen solchen Typ bereit: ein XmlListModel. Diesem üergeben wir lediglich eine URL zur RSS-XML-Datei sowie einen Query-String, der beschreibt, welche Daten aus dem XML wir abfragen wollen. Dazu fügen wir einfach folgenden Code innerhalb des oben implementierten Rectangle-Blocks ein:
XmlListModel {
id: xmlModel
source: "http://www.mobileqt.de/blogposts.rss"
query: "/rss/channel/item"
XmlRole { name: "title"; query: "title/string()" }
XmlRole { name: "guid"; query: "guid/string()" }
XmlRole { name: "link"; query: "link/string()" }
XmlRole { name: "pubDate"; query: "pubDate/string()" }
}
Die zusätzlichen XMLRole-Definitionen geben an, welches Element wir auf welche Variable abbilden wollen. Der String innerhalb der title-Tags im XML wird also innerhalb des Views als Variable title verfügbar sein, usw.
Damit ist die Hauptarbeit eigentlich schon erledigt. Wir müssen nun noch dem View mitteilen, dass er genau dieses Modell für die Anzeige von Daten verwenden soll. Dazu fügen wir dem ListView-Element noch folgende Zeile hinzu:
model: xmlModel
Im Prinzip greift der View nun auf das Modell zu, aber wenn man die Anwendung jetzt startet, bleibt der Bildschirm trotzdem leer. Wir müssen dem View noch mitteilen, wie er die einzelnen Elemente des Modells genau darstellen soll. Dazu dienen in QML die sogenannten “Delegates”. Ein Delegate besteht aus einem oder mehreren GUI-Elemente, die Zugriff auf die im Modell definierten Variablen bzw. Rollen haben. Um einfach eine Liste aller RSS-Elemente anzuzeigen, reicht im Prinzip zunächst einmal ein einfaches Textelement. Dazu fügt man in den ListView noch folgende Zeile hinzu:
delegate: Text { text: pubDate + ": " + title }
Wenn man die Anwendung jetzt startet, sieht man schon einmal die Elemente in einer Liste. Schön sieht das aber noch nicht aus. Außerdem soll ja ein Klick auf einen der Einträge später dann auch eine Aktion auslösen. Dazu implementieren wir als nächstes unser eigenes, aus QML-Primitiven aufgebautes GUI-Element.
Eigene GUI-Elemente komponieren
Um ein item-Element des RSS anzuzeigen, werden wir nun unser eigenes Widget implementieren. Dieses soll einigermaßen schön aussehen sowie bei einem Klick-Event (per Touch oder Maus) ein Signal aussenden, das wir dann später weiterverarbeiten können. Für die Gestaltung setzen wir das Element einfach aus ein paar der Primitiven wie einem Rechteck und Textelementen zusammen.
Zunächst wollen wir aber das Element in einer eigenen QML-Datei implementieren. Dazu fügen wir dem Projekt eine solche hinzu. Klickt im Projektbaum mit der rechten Maustaste auf das Projekt und wählt Hinzufügen:

Im sich öffnenden Dialog wählt ihr als Dateityp QML → QML-Datei. Nach Weiter solltet ihr im nächsten Schritt als Pfad den schon vorhandenen Ordner innerhalb des qml-Ordners des Projekts auswählen. Das ist der Ordner, in dem auch die Datei main.qml liegt (in meinem Beispielprojekt ist es der Ordner qml/HalloQml). Nur dann können wir das neue GUI-Element direkt ohne Umwege in main.qml verwenden. Als Name wählen wir RssListItem:

Im letzten Schritt noch Abschließen, und schon habt ihr eine neue QML-Datei RssListItem.qml in eurem Projekt. Zunächst definieren wir darin das Aussehen unseres Elements, sowie ein paar Felder für den Textinhalt, die wir später mit den Variablen des Modells füllen. Der komplette Code dazu sieht folgendermaßen aus:
import Qt 4.7
Item {
id: rssItem
property alias text: itemText.text
property alias date: itemDate.text
property alias backgroundcolor: rectBackground.color
signal clicked
height: itemDate.height + itemText.height + 20
width: parent.width
Rectangle {
id: rectBackground
anchors.fill: parent
color: "lightgrey"
border.color: "darkgrey"
border.width: 2
Item {
Text {
id: itemDate
font.pixelSize: 22
}
Text {
id: itemText
anchors.margins: 10
anchors.top: itemDate.bottom
font.pixelSize: 30
width: 360
wrapMode: Text.WordWrap
}
}
}
}
Zu Beginn definieren wir also, nach der üblichen import-Anweisung, ein Item-Element. Items dienen in QML meist dazu, andere GUI-Elemente zu gruppieren. So lassen sich mehreren Elementen gemeinsame Layout-Angaben oder “aktive” Flächen für Mausklicks und Gesten zuweisen. In unserem Fall werden wir beides benötigen. Nach der id definieren wir die sogenannten properties unseres Elements. Wir wollen später für jeden einzelnen Eintrag die Texte für das Veröffentlichungsdatum, den Titel des RSS-Eintrags, sowie eine Hintergrundfarbe setzen können. Damit können wir dem gerade aktiven Element eine andere Hintergrundfarbe geben als den anderen Elemente der Liste. Die properties sind allesamt als alias definiert. Das heißt, sie verweisen lediglich auf bestimmte Werte in Unterelemente, in diesem Fall auf das Unterlement Rectangle sowie die beiden Text-Elemente. Verweise auf Elemente erfolgen in QML, ähnlich wie in HTML und Javascript, grundsätzlich über die id der Elemente. Die Angabe itemText.text verweist also auf den Wert des text-Feldes innerhalb des Elements mit der ID itemText. Da es sich dabei um eine Element des Typs Text handelt, ist der Wert des text-Feldes genau derjenige Text, der auf dem Bildschirm angezeigt wird.
Nach den Properties definieren wir noch ein Signal, das später ausgesendet werden wird, sobald ein Mausklick auf das Element erfolgt. Die Verarbeitung der Signale folgt dabei dem Signal-Slot-Konzept, dass in Qt die zentrale Rolle bei der Ablaufsteuerung von Anwendungen einnimmt. QML fügt sich also an dieser Stelle nahtlos in das Qt-Framework ein.
Anschließend definieren wir noch Höhe und Breite unseres Elements sowie seine Unterelemente. Normalerweise müssen für jedes Element genaue Angaben für sein Layout gemacht werden. Dazu dienen in QML einmal die Größe von Elemente, zum anderen die sogenannten anchors, die die Positionierung des Elements innerhalb des Layouts bestimmen. Das Element kann dazu an allen anderen sichtbaren Elementen ausgerichtet werden, zusätzlich gibt es die Möglichkeit einer absoluten Positionierung. Häufig muss man, gerade beim Einstieg in QML, mit diesen Angaben herumspielen, bis die Anwendung so aussieht, wie man es sich vorstellt. Ein erster Ansatzpunkt ist meist die Angabe anchors.fill: parent. Damit erbt das Element alle Layout- und Positionsangaben von seinem Elternelement. Anschließend kann man die einzelnen Angaben, wie beispielsweise Abstand nach links oder rechts, noch einmal speziell für dieses Element verfeinern. In unserem Fall erbt das Rechteck einfach alle Angaben von seinem Elternelement Item, wobei dessen Größe von uns definiert wurde und der ListView daraus die Positionierung des Item innerhalb der Liste ableitet. Die Textelemente ordnen wir innerhalb des Rechtecks untereinander an, indem wir dem zweiten Textelement (der Überschrift) die Angaben anchors.top: itemDate.bottom übergeben. Die Oberseite der Überschrift beginnt damit an der Unterseite des Datums, mit einem Abstand von 10 Pixeln (durch die Angabe anchors.margins: 10).
Das Textelement für die Überschrift muss außerdem eine feste Breite zugewiesen bekommen, damit die Angabe für den Zeilenumbruch funktioniert (wrapMode: Text.WordWrap).
Wer mit HTML und CSS gearbeitet hat, wird mit den meisten Angaben schnell zurecht kommen. Genau wie bei Webseiten muss man aber ein genaues Verständnis des Layoutmechanismus haben, um auf Anhieb das gewünschte Aussehen zu erreichen. Hier hilft eigentlich nur Erfahrung. Im Qt Designer gibt es zwar schon einen rudimentären WYSIWYG-Editor für QML, allerdings hat man eben wie auch bei HTML und CSS nur dann die größtmögliche Kontrolle, wenn man direkt im Code arbeitet. Mal sehen, was die Zukunft uns hier bringt.
Nun wollen wir unser eigenes Element aber auch als delegate im ListView verwenden. Dazu wechselt man zunächst zurück in die Datei main.qml und passt den Code des delegate-Attributs folgendermaßen an:
delegate: RssListItem {
text: title
date: pubDate
backgroundcolor: mainScreen.currentIndex == index ? "#9bf" : "lightgrey"
}
Die Attribute text, date und backgroundcolor entsprechen hier den properties unseres Elements, die wiederum, wie oben beschrieben, auf die entsprechenden Attribute der Unterlemente verweisen. Dem gerade aktiven Element der Liste weisen wir eine andere Hintergrundfarbe zu, indem wir den zentral gespeicherten Wert mainScreen.currentIndex mit dem aktuellen index-Wert des ListView vergleichen. Innerhalb des delegate-Attributs steht uns in dieser Variable der Index des gerade zu zeichnenden Listenelements zur Verfügung. Ein klassisches Beispiel für deklaratives Programmieren.
Übrigens: in einer QML-Datei stehen grundsätzlich alle Elemente in QML-Dateien desselben Ordners zur Verfügung, man braucht also keinen zusätzlichen Import für das RssListItem.
Wenn die Anwendung jetzt gestartet wird, wird schon das selbst entworfene GUI-Element für die Liste verwendet:

Was nun noch fehlt, ist die Aktion: bei Klick auf eines der Elemente soll die Webseite des Eintrags in einem WebView-Element angezeigt werden.
Und Action: Signale und Zustände
Der erste Schritt für die Benutzereingabe ist es, diejenigen Flächen zu deklarieren, in denen auf Eingaben reagiert werden soll. Dazu dient beispielsweise das QML-Element MouseArea, das wir in unserem Fall einfach dem Rechteck unseres RssListItem hinzufügen können. Dazu öffnet man wieder die Datei RssListIten.qml im Editor und fügt dem Rectangle-Element am Ende folgenden Code hinzu:
MouseArea {
id: mouseRegion
anchors.fill: parent
onPressed: rssItem.state = 'Pressed'
onReleased: rssItem.state = 'Default'
onClicked: { rssItem.clicked(); }
}
Der Mausklick-Bereich erhält wiederum eine ID und übernimmt per anchors.fill die Größe und Position des Rechtecks. Die letzte Zeile löst das von uns definierte Signal clicked() aus, sobald die MouseArea angeklickt wurde. Die zusätzlichen Angaben für onPressed und onReleased werden wir für einen netten Effekt verwenden: sobald das Element angeklickt wurde, wird der Text-Stil des Elements geändert, solange die Maustaste gedrückt wird. Auch dieses Verhalten definieren wir deklarativ, in diesem Fall über Zustände. Wir können dazu für jedes Element beliebig viele Zustände ad-hoc definieren. In unserem Fall hat unser Element schon einmal die beiden Zustände Pressed und Default, die Namen der Zustände sind dabei von uns gewählt und können beliebig gewählt werden.
Wir müssen dem RssListItem nun nur noch mitteilen, was ein Zustand genau für eine Aktion auslöst. In unserem Fall soll ein Wechsel des Zustandes nach Pressed den Stil des Textelements itemText ändern. Dazu definiert man in QML ein Array states, dass die Angaben für die einzelnen Zustände und Zustandsänderungen enthält. Um das Textelement bei Mausklick zu ändern, fügt man einfach folgenden Code an das Ende des äußeren Item-Elements mit der ID rssItem hinzu:
states:[
State {
name: "Pressed"
when: mouseRegion.pressed == true
PropertyChanges {
target: itemText
style: Text.Sunken
color: "white"
}
}
]
}
Der Text wird bei Klick auf ein Listelement nun weiß und erhält den Stil Text.Sunken. Wenn die Anwendung jetzt im Qt Simulator gestartet wird, kann man dieses Verhalten gleich ausprobieren. Unser Element kümmert sich also ganz allein um die Änderung des Text-Stils, in der Datei main.qml muss dazu nichts geändert werden.
Nun soll aber auch das Hauptfenster auf den Klick reagieren. Das Signal clicked() haben wir ja schon ausgelöst, jetzt müssen wir nur noch in main.qml darauf reagieren. Zunächst beschränken wir uns darauf, nach einem Klick das aktuelle Element mit der Hintergrundfarbe zu markieren. Dazu reicht es aus, in main.qml dem delegate-Attribut des RssListItem noch ein Attribut hinzuzufügen. Das gesamte delegate sieht dann so aus:
delegate: RssListItem {
text: title
date: pubDate
backgroundcolor: mainScreen.currentIndex == index ? "#9bf" : "lightgrey"
onClicked: mainScreen.currentIndex = index
}
Man reagiert also auf eigene Signale genauso, wie oben auf die eingebauten Signale der MouseArea. Dazu fügt man dem Element einfach ein Attribut mit dem Signal samt Präfix on hinzu. In unserem Fall wechseln wir einfach den zentralen currentIndex auf den neuen index, sobald wir das Signal empfangen. Besser gesagt: wir “deklarieren” die Zuweisung der Eigenschaft mainScreen.currentIndex für dasjenige Attribut, das den Empfang des Signals beschreibt.
Das reicht auch schon aus: wenn man die Anwendung nun startet, reagiert nicht nur der Text auf den Mausklick, nach Loslassen der Maustaste wird außerdem das gewählte Element mit einer anderen Hintergrundfarbe gekennzeichnet.
Bäumchen wechsle dich im Hauptfenster: Neuer Zustand, neuer View
Im Prinzip erfolgt die Anzeige der Webseite zu einem der Listeneinträge auf genau dieselbe Art und Weise wie der Wechsel des Text-Stils im Listeneintrag: ein Klick auf einen Eintrag weist dem Hauptelement mainScreen zunächst einen neuen Zustand zu. Dieser neue Zustand wiederum löst einen Wechsel des aktuellen Views aus, anstatt dem ListView zeigen wir einfach einen WebView an. Dieser Wechsel lässt sich darüber hinaus animieren, so dass schließlich zwischen Liste und Webseite eine butterweiche Überblendung stattfindet.
Zunächst definieren wir dazu in main.qml innerhalb des Recangle-Elements mit der id mainScreen einen weiteren View, dieses Mal ein WebView-Element:
WebView {
id: webview
opacity: 0
anchors.fill: parent
MouseArea {
anchors.fill: parent
onClicked: mainScreen.state = "Rsslist"
}
}
Der WebView stellt einfach Webseiten dar, gerendert wird der gesamte Inhalt der Seite von einer WebKit-Komponente. Dazu muss am Anfang der Datei das Qt-WebKit-Modul per import QtWebKit 1.0 geladen werden. Das hatten wir aber oben schon erledigt.
Der View bleibt zunächst unsichtbar, da wir das Attribut opacitity auf 0 gesetzt haben. Per anchors.fill weisen wir dem Element seine Position zu, der WebView liegt damit an exakt derselben Stelle wir der ListView, ist aber absolut durchsichtig. Bei Klick auf den View wollen wir zunächst einfach zurück in die Liste wechseln. Das heißt, die Webansicht ist zunächst mehr oder weniger unbrauchbar, man gelangt von der Liste zwar dorthin, aber dann bei Klick gleich wieder zurück. Das liegt daran, dass der WebView in QML zunächst keinerlei Funktionalität außer der Anzeige der Webseite bereitstellt. Weder kann man Scrollen, noch Zoomen, noch sonst irgendetwas. Für unsere Zwecke ist das zunächst ausreichend, weiter unten werde ich dann noch darauf eingehen, wie man den WebView weiter ausbauen und nützlicher gestalten kann.
Ein Zustand namens RssList haben wir also schon einmal benannt, dieser wird gesetzt, sobald auf den WebView geklickt wird. Umgekehrt soll nun aber ein Klick auf ein Listenelement einen Zustand für die Anzeige der Webseite setzen, und am Besten auch gleich die URL der Webseite im WebView laden. Dazu fügen wir dem onClicked-Attribut des delegate im ListView noch zwei Zeilen hinzu, so dass das Attribut folgendermaßen aussieht:
onClicked: mainScreen.currentIndex = index,
webview.url = xmlModel.get(index).link,
mainScreen.state = "Webview"
Die zwei zusätzlichen Zeilen laden die Webseite, in dem die Variable link für den aktuellen Eintrag aus dem Modell geladen wird und dem WebView als URL zugewiesen wird. Außerdem setzen wir einen Zustand namens Webview.
Was nun noch fehlt, ist die Definition der Zustandsübergänge. Beim Übergang zum Zustand Webview soll das WebView-Element angezeigt werden, beim Übergang nach Rsslist ausgeblendet werden. Wiederum definieren wir dazu ein Array states, dieses Mal in main.qml am Ende des Rectangle-Elements:
states: [
State{
name: "Webview"
PropertyChanges{
target: webview
opacity: 1
focus: true
}
PropertyChanges {
target: listviewRss
opacity: 0
}
},
State {
name: "Rsslist"
PropertyChanges{
target: webview
opacity: 0
focus: false
}
PropertyChanges {
target: listviewRss
opacity: 1
}
}
]
Die Übergange zwischen den Zuständen setzen jeweils den Wert opacity der beiden Elemente: eines davon wird durchsichtig gemacht, dass andere angezeigt. Startet man die Anwendung nun, dann kann man schon einmal die Listenelemente auswählen und bekommt die entsprechende Webseite angezeigt. Klickt man dann auf die Webseite, gelangt man zurück in den ListView.
Das Ganze lässt sich nun auf eine einfache Art und Weise verschönern. Dazu definiert man für den Übergang von einer opacity-Einstellung zu einer anderen einfach eine Animation. Wiederum erfolgt die Angabe deklarativ, und zwar innerhalb eines Array transitions. Dieses Array definiert man parallel zu states am Ende des Rectangle-Elements in main.qml:
transitions: [
Transition {
PropertyAnimation{
properties: "opacity"
duration: 1000
easing.type: "OutCubic"
}
}
]
Wenn sich also die Durchlässigkeit eines Elements unseres Hauptfensters ändert, dann wird nicht einfach der Wert gesetzt. Stattdessen wird innerhalb von 1000 Millisekunde (duration-Attribut) der Wert kubisch angenähert (easing.type-Attribut). Das war’s auch schon, die Überblendung zwischen unseren Views erfolgt jetzt durch Ein- und Ausblendungen.
Den WebView ausbauen
Der nächste logische Schritt wäre nun natürlich, die Anzeige der Webseite brauchbar zu gestalten, also zumindest ein Zoomen und Scrollen zu erlauben. Dies soll nicht mehr Teil dieses Artikels sein, aber ein Hinweis soll zumindest gegeben werden. Nokia stellt bei den deklarativen Qt-Demos einen QML-Webbrowser zur Verfügung, dessen QML-Elemente sich in unserer Anwendung nutzen lassen. Der erste Schritt wäre, die einzelnen QML-Dateien des Beispiels in den qml-Ordner unserer Anwendung zu kopieren und dann statt dem Standard-WebView den FlickableWebView des Demos zu verwenden. Diese Aufgabe sei aber dem engagierten Leser überlassen :-).


