Qt lernt JavaScript

QML – GUI-Entwicklung für mobile Benutzerschnittstellen
Kommentare

Die von Nokia im Rahmen von Qt 4.7 eingeführte Sprache QML hat in der Qt-Gemeinde für Unruhe gesorgt – konservativere Zeitgenossen (wie der Autor dieser Zeilen) hofften sogar darauf, dass das lästige Modephänomen schon bald den Weg alles Irdischen gehen würde.

Leider entpuppte sich die Sprache als höchst robust. In Qt 5.0 gilt sie sogar als „Favorit“ für die Entwicklung von mobilen Benutzerschnittstellen. Auch das von RIM entwickelte Cascades lässt sich am besten aus QML heraus ansprechen. Aus diesem Grund wollen wir uns nun die Frage stellen, was QML für alteingesessene Entwickler für Neuerungen bringt.

QML – was ist das?

Hinter der etwas sperrigen Abkürzung verbirgt sich die Abkürzung „Qt Modeling Language“. Damit ist die Aufgabe der Sprache auch schon gut beschrieben – es handelt sich dabei um ein Werkzeug zur Erstellung von Benutzeroberflächen.
Natürlich haben C++-Entwickler schon seit anno dazumal ansprechende GUIs entwickelt. Allerdings veränderten sich die Anforderungen der Benutzer – Stichwort iPhone – rapide, was sich natürlich auch auf die Komplexität der hinter einer Benutzerschnittstelle stehenden Logik auswirkt.
Selbstverständlich ist es möglich, derartige Schnittstellen ausschließlich in C++ zu realisieren. Allerdings arten derartige Versuche schnell in Kodierungsorgien aus – viel intelligenter wäre es, wenn man das GUI in einer dafür vorgesehenen Sprache (Stichwort „Domain Specific Language“) entwerfen könnte. Diese muss, ja soll, nicht zum Erstellen komplexer Applikationslogik geeignet sein – das ist eine Aufgabe, die C++ seit jeher gut erfüllt.

Alleinstehendes QML

Im Bereich der QML-Anwendungen gibt es zwei verschiedene Ansätze. Die Standalone-Applikation besteht aus einer qml-Datei, die in einem von Digia vorgegebenen und vom SDK automatisch generierten Viewer angezeigt wird. Die für die meisten Entwickler praxistauglichere Alternative ist eine Applikation mit einem einzelnen Formular, in dem eine QDeclarativeView das in QML gehaltene GUI hostet.
Am einfachsten bekommen Sie ein Projekt des zweiten Typs einsatzbereit, indem Sie in Qt Creator ein neues Projekt erstellen und als Vorlage eine Qt-GUI-Anwendung wählen. Quick-Anwendungen basieren auf dem QML Viewer, der sich nur schwer um eigene C++-Logik erweitern lässt.
Nach dem ersten Erstellen müssen Sie die .pro-Datei um die Inklusion des declarative-Moduls erweitern – ohne es können Sie keine QML-Anwendungen einsetzen:

QT += core gui declarative

Im nächsten Schritt müssen Sie der qml-Datei ein „Zuhause“ geben. Dazu öffnen Sie das Formular und weisen ihm ein bildschirmfüllendes QDeclarativeWidget zu. Die zum Erreichen des Resize-Verhaltens erforderlichen Einstellungen des Layoutsystems werden hier aus Platzgründen nicht näher besprochen.
Sodann ist es an der Zeit, die erste QML-Datei zum Projekt hinzuzufügen. Dazu empfiehlt es sich, die Hinzufügen-Funktion der IDE zu verwenden. Da die Datei von Haus aus im .pro-File nur als OTHER_FILE hinzugefügt wird, sollten Sie sie auch über eine Ressourcendatei zur Auslieferung anweisen.
Im Konstruktor von MainWindow.cpp verwenden Sie die SetSource-Funktion der QDeclarativeView, um das Fenster mit der Datei zu verdrahten (Listing 1). Damit fehlt nur mehr der Korpus der Datei. Adaptieren Sie das von Haus erstellte Skelett nach dem in Listing 2 dargestellten Schema.

MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::MainWindow)
{
  ui->setupUi(this);
  ui->declarativeView->setSource(QUrl("qrc:/qml/QMLFile.qml"));
}
import QtQuick 1.1

Rectangle {
  width: 200
  height: 100
  color: "darkgrey"
  radius: 20
  id: motherRect
  Rectangle
  {
    x: 2
    y: 2
    color: "lightgrey"
    width: motherRect.width-4
    height: motherRect.height -4
    radius: 20
  }
}

An dieser Stelle sehen wir einige wichtige Eigenschaften von QML-Code. Erstens besteht eine QML-Datei aus einer Gruppe von Objekten, die ineinander verschachtelt sind. Hier haben wir es mit einem Rechteck zu tun, das ein zweites Rechteck enthält. Beide haben eine Vielzahl von Parametern, die durch das „Hintereinanderschreiben“ von Parametername und -wert festgesetzt werden – diese Syntax erinnert stark an JSON.
Das Setzen des id-Parameters sorgt dafür, dass das äußere Rechteck „ansprechbar“ wird. Moderne GUIs haben die unangenehme Eigenschaft, aus hunderten (oder gar tausenden) Elementen zu bestehen – für Entwickler interessant sind davon freilich nur die wenigsten. Aus diesem Grund sind QML-Elemente erst einmal „anonym“, und werden erst durch das Zuweisen einer ID für andere Elemente ansprechbar.

QML und JavaScript

In JavaScript-Kreisen wurde das Erscheinen von QML stellenweise als „Sieg über C++“ gefeiert. Das ist bis zu einem gewissen Grad richtig, da QML auch einen vollwertigen JavaScript-Kern enthält – ob man damit allerdings komplexe Geschäftslogik entwickeln sollte, ist aus praktischer Sicht mehr als fragwürdig.
Im folgenden Schritt wollen wir die auf unsere Konstruktion abgesetzten Klicks „einfangen“. Dazu schreiben wir dem äußeren Rectangle eine MouseArea ein, die nach einem Klick die JavaScript-Funktion clickOccurred aufruft. Diese ist ebenfalls in der .qml-Datei deklariert (Listing 3).

Rectangle {
  ...
  MouseArea
  {
    anchors.fill:parent
    onClicked: clickOccurred()
  }
  function clickOccurred()
  {
    ...
  }
}

 

International PHP Conference

Jede Menge Wissen rund um JavaScript gibt es auch auf der diesjährigen International PHP Conference, die vom 1. bis 4. Juni in Berlin stattfindet. Da wäre beispielsweise der JavaScript Day am 4. Juni mit Session von Sebastian Springer, Jakob Westhoff oder Rainer Stropek. Darüber hinaus bietet die IPC interessierten Entwicklern 6 Power-Workshops und über 60 Sessions mit bestem Expertenwissen internationaler Speaker.

Die International PHP Conference 2014 findet vom 1. bis 4. Juni in Berlin statt und bietet einen umfassenden Überblick über aktuellste Entwicklungen im PHP-Umfeld. Und wer sich bis Donnerstag den 8. Mai anmeldet, kann bis zu 150 Euro sparen und sich ein Intellibook-Tablet sichern.

Die International PHP Conference ist der traditionelle Treffpunkt für PHP-Entwickler und -Enthusiasten, bei dem Sie neben den klassischen PHP-Vorträgen auch Zugang zu dem gesamten Angebot der parallelen webinale genießen.

International PHP Conference 2014 
Aufmacherbild: Program code on a monitor von Shutterstock / Urheberrecht: scyther5

[ header = Seite 2: Animation, automatisiert ] 

Animation, automatisiert

Einer der wichtigsten Aspekte des neuen GUIs im iPhone war, dass die Übergänge zwischen den diversen Elementen nicht ruckartig erfolgten. Stattdessen setzte Apple auf weiche Animationen, die den Benutzer von Zustand zu Zustand geleiteten.
QML erleichtert das Erstellen derartiger Effekte wesentlich. Anstatt die Wertänderungen von Hand mit einem Timer zu synchronisieren, teilen Sie der Sprache mit, wie die Änderung zu erfolgen hat. Das Framework setzt die Anweisungen danach auf Zuruf automatisch um.
Der einfachste Weg zum Erreichen eines animierten Übergangs ist das Verwenden eines Behaviors. Dabei handelt es sich um eine Eigenschaft, die das Verhalten des Steuerelements bei einer Änderung des Werts eines bestimmten Attributs beeinflusst. In unserem Beispiel genügen dazu die in Listing 4 gezeigten, kleinen Adaptionen am Quellcode.

Rectangle {
  ...
  Behavior on color 
  {
    PropertyAnimation
    {
      duration: 3000 
    }
  }
  ...
  function clickOccurred()
  {
    innerRect.color="lightblue"
    motherRect.color="darkblue"
  }
}

Die hier gezeigte Struktur ist relativ einfach. Wir haben dem Rectangle ein Behavior eingeschrieben, das Veränderungen der Color-Eigenschaft über eine drei Sekunden dauernde PropertyAnimation abwickelt. In clickOccurred passen wir die Farben an, wenn ein Klick auf die MouseArea auftritt.
Wenn Sie das Programm nun ausführen, so ändert sich die Farbe des Steuerelements langsam aber sicher von Grau nach Blau. Die Animation erfolgt dabei vollautomatisch und ohne jede weitere Programmierung Ihrerseits. Übrigens ist das Framework nicht auf Anpassungen von Farben beschränkt. Es ist auch legitim, ein Behavior anzulegen, das die Position eines Steuerelements am Bildschirm beeinflusst.

QML als Zustandsautomat

Leider ist es uns noch nicht möglich, unser Steuerelement nach der Farbänderung wieder in den Ursprungszustand zu versetzen. Da die Änderungsanträge vom Framework sequenziell verarbeitet werden, könnten wir die Funktion clickOccurred erweitern.
Wesentlich lehrreicher ist es, stattdessen auf den in QML integrierten Zustandsautomaten zurückzugreifen. Er erlaubt uns das automatische Anpassen der Benutzerschnittstelle in Reaktion auf eingehende Ereignisse – auf Wunsch übernimmt das Framework sogar die Überwachung der Trigger für uns (Listing 5).

Rectangle {
  ...
  id: motherRect
  Behavior on color
  {
    PropertyAnimation
    {
      duration: 3000
    }
  }
  Rectangle
  {
    ...
    id: innerRect
    Behavior on color
    {
      PropertyAnimation
      {
        duration: 3000
      }
    }
  }
  MouseArea
  {
    anchors.fill:parent
    id: mouseHouse
    hoverEnabled:true
  }
  states:
  [
    State
    {
      when: mouseHouse.containsMouse
      PropertyChanges
      {
        target: innerRect
        color: "lightblue"
      }
      PropertyChanges
      {
        target: motherRect
        color: "darkblue"
      }
    },
    State
    {
      when: !mouseHouse.containsMouse
      PropertyChanges
      {
        target: innerRect
        color: "lightgrey"
      }
      PropertyChanges
      {
        target: motherRect
        color: "darkgrey"
      }
    }
  ]
}

Diesmal haben wir das Behavior sowohl dem inneren als auch dem äußeren Rectangle zugewiesen. Das States-Array (beachten Sie bitte die Syntax mit den []) enthält zwei Zustände, deren Aktivierung über das When-Property bestimmt ist. Die eigentlichen Änderungen finden sich als PropertyChanges-Attribute des jeweiligen State-Objekts – jedes PropertyChanges-Objekt beeinflusst eines der Rectangles.
Zu guter Letzt noch ein wichtiger Hinweis zur Kombination aus Behaviors und States. Kreative Entwickler nutzen die Fähigkeit des Frameworks, den „Ursprungszustand“ eines Steuerelements nach dem Ende einer Zustandsänderung automatisch wiederherzustellen. Leider führt das in der Praxis zu höchst schwierig zu debuggenden Fehlern, wenn die Animation mehrmals hintereinander getriggert wird – weitere Informationen zum Thema finden sich hier.

Fazit

Die hier vorgestellten Funktionen sollen Ihnen einen kleinen Einblick in die Möglichkeiten der GUI-Erstellung mit QML geben. Es ist völlig illusorisch, in einem halben Beitrag in einem Fachmagazin die komplette Breite der Sprache vorzustellen – würde dieser Artikel QML als Ganzes behandeln wollen, so wäre das Entwickler Magazin doppelt so dick.
Für erfahrene Qt-Entwickler ist eine genaue Betrachtung der Features nicht allzu relevant – als alte Hasen finden Sie sich in der Dokumentation schnell zurecht. Viel wichtiger ist es, sich die Zeit zur Beschäftigung mit dem Framework zu nehmen. Nach der Überwindung des inneren Widerstands gegen JavaScript geht das Erstellen von GUIs damit flott von der Hand – also nichts wie ran an den Speck!

 

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -