Qt wiki will be updated on October 12th 2023 starting at 11:30 AM (EEST) and the maintenance will last around 2-3 hours. During the maintenance the site will be unavailable.
Quick Start QML Programming/de
[toc align_right="yes" depth="2"]
Schnelleinstieg in die Programmierung mit QML
Willkommen in der Welt von QML, der deklarativen UI Sprache. In diesem Schnelleinstieg werden wir eine einfache Texteditor-Anwendung erstellen unter benutzung von QML. Nach dem Sie diese Anleitung durch haben, sollten Sie in der Lage sein eigene QML und Qt C++ Anwendungen zu erstellen.
QML um Benutzerschnittstellen zu erstellen
Die Anwendung, die wir erstellen, ist ein einfacher Texteditor der Text laden, speichern und ändern können wird. Diese Anleitung besteht aus zwei Teilen. Der erste Teil wird erklären wie das Design der Anwendung sowie ihr Verhalten mit Hilfe deklarativer Sprache in QML erstellt wird. Im zweiten Teil wird das Laden und Speichern von Dateien in Qt C++ implementiert. Mittels "Qts Meta-Object System":http://doc.qt.nokia.com/4.7/metaobjects.html können wir C++ Funktionen als Eigenschaften für QML Elemente zur Verfügung stellen. Unter Anwendung von QML und Qt C++ können wir effektiv die Benutzerschnittstelle von der Buisnesslogik trennen.
p=. Texteditor
Um das QML Beispiel auszuführen reicht es dem "qmlviewer":http://doc.qt.nokia.com/4.7/qmlviewer.html die QML Datei als Argument zu übergeben. Der C++ Teil dieser Anleitung setzt grundlegendes Wissen um den Qts Kompilierungsprozess voraus.
Knopf und Menü definieren
Grundelement - ein Knopf
Wir beginnen unseren Texteditor mit dem Erschaffen eines Knopfes. Funktionstechnisch hat ein Knopf einen Maussensitiven Bereich und eine Beschriftung. Knöpfe führen eine Aktion aus nach dem der Benutzer drauf geklickt hat.
In QML ist das "Rechteck":http://doc.qt.nokia.com/4.7/qml-rectangle.html das grundlegende visuelle Element. Das
Rectangle
Element hat Eigenschaften zu Kontrolle des Aussehens und Position.
import Qt 4.7
Rectangle{
id:simplebutton
color: "grey"
width: 150
height: 80
Text{
id: buttonLabel
text: "button label"
anchors.centerIn: parent;
anchors.verticalCenterOffset: –1
}
}
Zunächst erlaubt
import Qt 4.7
dem qmlviewer QML Elemente zu importieren, die wir später verwenden werden. Diese Zeile muß in jeder QML Datei vorhanden sein. Beachten Sie die Version der Qt Module, die im import mit angegeben wird. Dieses einfache Rechteck hat einen eindeutigen Bezeichner,
simplebutton
, der an die
id
Eigentschaft gebunden ist.
Rectangle
s Elementeigenschaften werden an Werte gebunden, in dem die Eigenschaft gefolgt von Doppelpunkt und dem Wert notiert werden. Im Codeausschnitt wird die Farbe grau an die Farbeigenschaft des Rechteckes gebunden. Ähnlich verbinden wir die Breite
width
und Höhe
height
des Rechteckes. Das "Textelement":http://doc.qt.nokia.com/4.7/qml-text.html ist ein nichteditierbares Textfeld. Wir benennen dieses Textelement mit
buttonLabel
. Um den Textinhalt des Textfeldes zu setzen binden wir die
text
-Eigenschaft an einen Wert. Die Beschriftung ist im Rechteck Element enthalten und wird innerhalb des Elternelements zentriert in dem wir die Anker (
anchors
) Eigenschaft des Textelementes dem Elternelement zuweisen —
simplebutton
. Anker können auch an Anker anderer Elemente gebunden werden, um Layoutzuweisungen zu erleichtern. Wir werden diesen Code als
SimpleButton.qml
abspeichern. Das Ausführen von qmlviewer mit dieser Datei als Argument zeigt uns das graue Rechteck mit einer Textuellen Bezeichnung.
p=. Einfacher Knopf
Um die Klickfunktionalität des Knopfes zu implementieren, greifen wir auf QMLs Ereignisbehandlung zurück. QMLs Ereignisbehandlung ist dem "Qt's signal and slot":http://doc.qt.nokia.com/4.7/signalsandslots.html Mechanismus sehr ähnlich. Signale werden ausgelöst und damit verbundene Slots werden aufgerufen.
Rectangle{
id:simplebutton
…
MouseArea{
id: buttonMouseArea
anchors.fill: parent //anchor all sides of the mouse area to the rectangle's anchors
//onClicked handles valid mouse button clicks
onClicked: console.log(buttonLabel.text + " clicked" )
}
}
Wir fügen ein "MouseArea":http://doc.qt.nokia.com/4.7/qml-mousearea.html Element in unseren
simplebutton
ein.
MouseArea
Elemente beschreiben den interaktiven Bereich in dem Mausbewegungen registriert werden. Bei unserem Knopf verankern wir den gesamten "MouseArea":http://doc.qt.nokia.com/4.7/qml-mousearea.html Bereich an das Elternelement —
simplebutton
. Die
anchors.fill
Syntax ist ein Weg um an die
fill
Eigenschaft innerhalb einer Gruppe von Ankereigenschaften zu kommen. QML benutzt "Ankerbasierte Layouts":http://doc.qt.nokia.com/4.7/qml-anchor-layout.html an Stellen wo Elemente an andere Elemente ankern können um robuste Layouts zu ermöglichen. Die
MouseArea
hat viele Signalbehandlungsroutinen, die während einer Mausbewegung aufgerufen werden, die innerhalb der angegebenen
MouseArea
auftreten. Eine davon ist
onClicked
. Diese wird immer dann aufgerufen, wenn akzeptierter Mausknopf gedrückt wird; Linksklick ist dabei der Standard. Wir können mit der
onClicked
Routine Aktionen verbinden. In unserem Beispiel gibt
console.log()
einen Text aus bei jedem Klick in die MouseArea. Die Funktion
console.log()
ist eine nützliche Funktion um Funktionalitäten auszutesten oder einen Text auszugeben. Der Code in
SimpleButton.qml
genügt um einen Knopf anzuzeigen und einen Text für jeden getätigten Klick auszugeben.
Rectangle {
id:Button
…
property color buttonColor: "lightblue"
property color onHoverColor: "gold"
property color borderColor: "white"
signal buttonClick()
onButtonClick: {
console.log(buttonLabel.text + " clicked" )
}
MouseArea {
onClicked: buttonClick()
hoverEnabled: true
onEntered: parent.border.color = onHoverColor
onExited: parent.border.color = borderColor
}
// determines the color of the button by using the conditional operator
color: buttonMouseArea.pressed ? Qt.darker(buttonColor, 1.5) : buttonColor
}
Ein voll funktioneller Knopf ist in
Button.qml
. Der Codeschnipsel in diesem Artikel läßt Codestücke, die bereits erklärt wurden, weg. Benutzereigene Eigenschaften werden durch die
property typ name
Syntax definiert. Im code wird die Eigenschaft
buttonColor
mit dem typ
color
deklariert und an den Wert
"lightblue"
gebunden. Die Eigenschaft
buttonColor
wird später für eine bedingte Operation verwendet um die Füllfarbe des Knopfes zu bestimmen. Beachten Sie, daß eine Wert Zuweisung durch den = Operator möglich ist, zusätzlich zu der Wertbindung durch den : Operator. Benutzereigene Eigenschaften erlauben es interne Sachen von außerhalb des
Rectangle
Geltungsbereich erreichbar zu machen. Es gibt grundlegende "QML Typen":http://doc.qt.nokia.com/4.7/qdeclarativebasictypes.html wie
int
,
string
,
real
, so wie
variant
genannten Typ. Durch die Anbindung der
onEntered
und
onExited
Signalroutinen an Farben, wird der Knopfrand gelb solange die Maus sich über dem Knopf befindet, und ändert sich wieder zurück sobald die Maus den Knopf verläßt. Ein
buttonClicked()
Signal wird in
Button.qml
durch das Platzieren des
signal
Schlüsselwortes vor dem Signalnamen deklariert. Alle Signale bekommen ihre Signalroutine automatisch, ihren Namen mit
on
beginnend, generiert. Als Ergebnis ist
onButtonClick
buttonClick
s Signalroutine.
onButtonClick
wird dann eine auszuführende Aktion zugewiesen. In unserem Knopf Beispiel ruft die
onClicked
Signalroutine einfach
onButtonClick
auf, die einen Text anzeigt. Die
onButtonClick
Routine ermöglicht externen Objekten einfachen Zugrif auf den Mausbereich. Zum Beispiel können Gegenstände mehrere
MouseArea
Deklarationen besitzen und ein
buttonClick
Signal macht die Unterscheidung zwischen den verschiedenen
MouseArea
Signalroutinen einfacher. Wir haben nun das Basiswissen um Gegenstände in QML zu implementieren, die in der Lage sind Mausbewegungen zu behandeln. Wir haben eine Beschriftung innerhalb eines
Rectangle
Objektes erstellt, dessen Eigenschaften verändert und Verhalten implementiert, das auf Mausbewegungen reagiert. Die Idee Elemente innerhalb anderer Elemente zu erstellen wird in der Texteditor Anwendung durchgehend wiederholt.
Dieser Knopf ist unbrauchbar, es sei denn er wird als eine Komponente verwendet um eine Aktion auszuführen. Im nächsten Abschnitt werden wir bald ein Menü erstellen, das einige dieser Knöpfe enthält.
p=. Knopf
Eine Menüseite erstellen
Bisher haben wir das Erstellen von Elementen und das Zuweisen des Verhaltens in einer QML Datei besprochen. In diesem Abschnitt werden wir den Import anderer QML Elemente besprechen, und wie man bereits erstellte Komponenten wiederverwendet um andere Komponenten zu erstellen.
Menüs zeigen den Inhalt einer Liste. Jedes Element hat die Fähigkeit eine Aktion auszuführen. In QML können wir auf unterschiedliche Weisen ein Menü erstellen. Zunächst werden wir ein Menü erstellen, das Knöpfe enthält, die letztendlich unterschiedliche Aktionen durchführen. Der Menücode befindet sich in
FileMenu.qml
.
import Qt 4.7 import the main Qt QML module
import "folderName" import the contents of the folder
import "script.js" as Script import a Javascript file and name it as Script
Die oben gezeigte Syntax zeigt, wie das
import
Schlüsselwort zu benutzen ist. Dieses ist nötig um "JavaScript":https://developer.mozilla.org/de/JavaScript Dateien verwenden zu können, oder QML Dateien, die nicht im gleichen Verzeichnis liegen. Da
Button.qml
im selben Verzeichnis liegt wie
FileMenu.qml
, brauchen wir
Button.qml
nicht zu importieren um es verwenden zu können. Wir können direkt ein
Button
Element erstellen durch die Deklaration
Button{}
, ähnlich der
Rectangle{}
Deklaration.
In FileMenu.qml:
Row{
anchors.centerIn: parent
spacing: parent.width/6
Button{
id: loadButton
buttonColor: "lightgrey"
label: "Load"
}
Button{
buttonColor: "grey"
id: saveButton
label: "Save"
}
Button{
id: exitButton
label: "Exit"
buttonColor: "darkgrey"
onButtonClick: Qt.quit()
}
}
In
FileMenu.qml
deklarieren wir drei
Button
Elemente. Sie werden innerhalb eines "Row":http://doc.qt.nokia.com/4.7/qml-row.html Elementes deklariert, einem Stellungregler, der seine Kinder vertikal ausrichtet. Die
Button
Deklaration ist in Button.qml abgelegt, was die gleiche Datei ist, die wir in vorherigem Abschnitt verwendet haben. Neue Eigenschaftbindungen können innerhalb der neu erstellten Knöpfe deklariert werden, was die bereits in der Button.qml gesetzte Eigenschaften überschreibt. Der
exitButton
genannte Knopf beendet und schließt das Anwendungsfenster beim Klicken. Beachten Sie, daß die Signalroutine
onButtonClick
in
Button.qml
zusätzlich zu
onButtonClick
Routine im
exitButton
aufgerufen wird.
p=. Menü
Die
Row
Deklaration wird in einem
Rectangle
vorgenommen, um einen rechteckigen Container für die Knopfzeile zu erstellen. Dieses zusätzliche Rechteck stellt eine indirekte Möglichkeit die Knopfzeile in einem Menü zu organisieren. Die Deklaration des Bearbeitungsmenü ist zu diesem Zeitpunkt sehr ähnlich. Das Menü besitzt Knöpfe mit Beschriftungen:
Copy
,
Paste
und
Select All
.
p=. Bearbeitungsmenü
Mit unserem Wissen über das Importieren und Anpassen früher erstellter Komponenten ausgerüstet können wir nun diese Menüseiten kombinieren um eine Menüleiste zu erstellen, bestehend aus Knöpfen um das Menü auszuwählen, und schauen wie wir die Daten unter Verwendung von QML strukturieren können.
Menüleiste implementieren
Unsere Texteditor Anwendung wird einen Weg benötigen um Menüs in einer Menüzeile anzuzeigen. Die Menüleiste wird zwischen den verschiedenen Menüs umschalten und der Benutzer kann entscheiden welches Menü angezeigt werden soll. Das Menü Umschalten deutet darauf hin, daß wir mehr Struktur benötigen als simples anzeigen in einer Zeile. QML verwendet Modele und Ansichten um Daten zu strukturieren und sie anzuzeigen.
Datenmodelle und Ansichten benutzen
QML hat unterschiedliche "Datenansichten":http://doc.qt.nokia.com/4.7/qdeclarativemodels.html, die Datenmodelle anzeigen. Unsere Menüleiste wird Menüs in einer Liste anzeigen; mit Menünamen in der Kopfzeile. Die Liste der Menüs sind innerhalb von
VisualItemModel
deklariert. Das "VisualItemModel":http://doc.qt.nokia.com/4.7/qml-visualitemmodel.html Element beinhaltet Elemente, die bereits Ansichten besitzen, wie die
Rectangle
Elemente und importierte UI Elemente. Andere Modelltypen wie das "ListModel":http://doc.qt.nokia.com/4.7/qml-listmodel.html Element brauchen einen Delegierer um ihre Daten anzuzeigen. Wir deklarieren zwei visuelle Dinge in
menuListModel
, das
FileMenu
und das
EditMenu
. Wir passen die zwei Menüs an und zeigen sie an unter Verwendung von einem "ListView":http://doc.qt.nokia.com/4.7/qml-listview.html. Die
MenuBar.qml
Datei beinhaltet die QML Deklarationen und ein einfaches
edit
Menü ist in der
EditMenu.qml
definiert.
VisualItemModel {
id: menuListModel
FileMenu{
width: menuListView.width
height: menuBar.height
color: fileColor
}
EditMenu{
color: editColor
width: menuListView.width
height: menuBar.height
}
}
Das "ListView":http://doc.qt.nokia.com/4.7/qml-listview.html Element wird ein Model anzeigen, das vom Delegierer bereitgestellt wird. Der Delegierer kann die Modeldaten so deklarieren, daß sie in einem Zeilenelement angezeigt werden, oder in einem Gitternetz. Unser
menuListModel
hat bereits sichtbare Dinge, deshalb brauchen wir keinen Delegierer zu deklarieren.
ListView {
id: menuListView
//Anchors are set to react to window anchors
anchors.fill:parent
anchors.bottom: parent.bottom
width:parent.width
height: parent.height
//the model contains the data
model: menuListModel
//control the movement of the menu switching
snapMode: ListView.SnapOneItem
orientation: ListView.Horizontal
boundsBehavior: Flickable.StopAtBounds
flickDeceleration: 5000
highlightFollowsCurrentItem: true
highlightMoveDuration:240
highlightRangeMode: ListView.StrictlyEnforceRange
}
Zusätzlich erbt
ListView
von "Flickable":http://doc.qt.nokia.com/4.7/qml-flickable.html, was die Liste auf Mausverschiebungen und andere Gesten reagieren lässt. Der letzte Teil des oberen Codes setzt
Flickable
Eigenschaften um das gewünschte schnellende Bewegen in unserer Ansicht zu bewirken. Speziell die Eigenschaft
highlightMoveDuration
verändert die Dauer des schnellenden Übergangs. Ein größerer
highlightMoveDuration
Wert resultiert in langsamerer Menü Umschaltung. Die
ListView
behält die Modeleinträge durch einen index und alle visuellen Elemente im Model sind durch diesen Index zugänglich, in der Reihenfolge ihrer Deklarierung. Das Ändern des
currentIndex
ändert praktisch das hervorgehobene Element in der
ListView
. Die Kopfzeile unseres Menüs führt diesen Effekt beispielhaft vor. Es gibt zwei Knöpfe in der Zeile, beide ändern durch Betätigen das aktuelle Menü. Der
fileButton
Knopf ändert das aktuelle Menü zu Dateimenü, der index ist hier 0, da
FileMenu
als Erstes in der
menuListModel
deklariert ist. Ähnlich ändert der
editButton
das aktuelle Menü zu
EditMenu
wenn er geklickt wird. Das
labelList
Rechteck hat einen z-Wert von 1, kennzeichnend, daß es im Vordergrund der Menuleiste angezeigt wird. Elemente mit einem höheren z-Wert werden vor Elementen mit einem niedrigeren z-Wert angezeigt. Der Standard z-Wert ist 0.
Rectangle{
id: labelList
…
z: 1
Row{
anchors.centerIn: parent
spacing:40
Button{
label: "File"
id: fileButton
…
onButtonClick: menuListView.currentIndex = 0
}
Button{
id: editButton
label: "Edit"
…
onButtonClick: menuListView.currentIndex = 1
}
}
}
Die Menüleiste, die wir gerade erstellt haben, kann benutzt werden um Menüs zu erreichen oder durch das Klicken auf die oberen Menünamen. Umschalten der Menümasken ist intuitiv und schnell.
p=. Menüleiste