Getting Started Programming with QML/de

From Qt Wiki
Jump to navigation Jump to search
This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine.
Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean.

Erstellen graphischer Oberflächen mit QML

Willkommen in der Welt von QML, der deklarativen UI-Sprache, Qt Markup Language. In dieser Einführung werden wir eine einfache Texteditor-Applikation mit Hilfe der QML erstellen. Nach dem Lesen dieser Einführung sollten Sie in der Lage seine eigenen Applikationen mit QML und Qt C++ zu entwickeln. Die Applikation, die wir bauen wollen, ist ein einfacher Texteditor, der laden, speichern und einige Textmanipulationen durchführen kann. Diese Anleitung besteht aus zwei Teilen. Der erste Teil befasst sich mit dem Design des Aussehens und dem Verhalten der Applikation mit Hilfe der deklarativen Sprache QML. Der zweite Teil, in dem es um das Laden und Speichern von Texten geht, wird in Qt C++ implementiert. Durch die Verwendung von Qt's Meta-Object System können wir C+-Funktionen als Eigenschaften definieren, die QML-Elemente verwenden können. Unter Zuhilfenahme von QML und Qt C++ können wir auf effiziente Weise die Benutzeroberfläche von der Applikationslogik entkoppeln.

    QQmlApplicationEngine engine;
    engine.load(QUrl("qrc:/qml/texteditor.qml"));
    if (engine.rootObjects().isEmpty())
        return -1;

Um das QML-Beispiel zu starten genügt es das QQmlApplicationEngine-Object (engine) mit der QML-Datei (texteditor.qml) als Argument aufzurufen. Für den C++ Teil dieser Einführung gehen wir davon aus, dass der Leser grundlegendes Wissen über das Kompilieren von Qt-Anwendungen hat.

Erzeugen eines Schalters und eines Menus

Basiselemente - der Schalter

Wir starten unseren Texteditor mit dem Erzeugen eines Schalters. Prinzipiell besteht ein Schalter aus einem Maus-sensitiven Bereich und einem Label. Schalter lösen eine Aktion aus, wenn der Anwender den Schalter drückt. In QML ist das einfachste sichtbare Element ein Rechteck. Das Rechteck hat Eigenschaften, mit denen das Aussehen und der Ort gesteuert werden können.

Als erstes importieren wir die Qt 6 QML-Elemente in den qmlviewer, die wir später verwenden. Die Zeile muss in jeder QML-Datei vorhanden sein. Beachten Sie, dass die Versionsnummer in der Import-Anweisung enthalten ist.

Dieses einfache Rechteck hat einen eindeutigen Namen, simplebutten, durch den dieses Element identifiziert wird. Die Eigenschaften des Rechtecks werden durch eine Liste von Eigenschaften jeweils gefolgt von einem Doppelpunkt und dem Wert festgelegt. Im Programmbeispiel wird die Farbe des Rechtecks auf grau festgelegt. In der gleichen Art und Weise werden die Breite und die Höhe festgelegt.

Das Textelement ist ein nichteditierbares Textfeld. Wir nennen dieses Textelement buttonLabel. Um den Text des Textfelds zu setzen ändern wir den Wert der Text-Eigenschaft. Das Textfeld ist Bestandteil des Rechtecks und um es in der Mitte des Rechtecks zu zentrieren verbinden wir die Anker des Textelement mit dem Rechteck, das simplebutton heißt. Anker können mit Ankern von anderen Elementen verbunden werden, um die Anordnung von Elementen zu vereinfachen. Wir sollten den Quelltext unter dem Namen SimpleButton.qml speichern. Wenn man den qmlviewer mit dieser Datei als Argument aufruft wird ein graues Rechteck mit einem Textfeld angezeigt.

Ein einfacher Schalter

Um die Funktionalität zum Anklicken des Schalters zu implementieren, können wir die Ereignisbehandlung von QML verwenden. Die Ereignisbehandlung von QML ist vergleichbar mit dem Signal und Slot Mechanismus der Qt. Signale werden gesendet und der verbundenen Slots 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-Element zu unserem simplebutton hinzu. MouseArea-Elemente beschreiben die interaktiven Bereiche, in denen Mausbewegungen erkannt werden. Für unseren Schalter setzen wir den Anker der gesamten MouseArea auf das Elternelement, den simplebutton. Die anchors.fill Syntax ist ein Weg um auf eine spezielle Eigenschaft mit dem Namen fill die sich in einer Gruppe von Eigenschaften mit dem Namen anchors befindet zuzugreifen. QML verwendet Anker-basierte Layouts in denen verschiedene Elemente miteinander verankert sein können, um robuste Layouts zu erzeugen.

Die MouseArea hat viele Signal-Handler, die aufgerufen werden, während der Mauszeiger innerhalb der Grenzen der MouseArea beweget wird. Eines davon ist onClicked und wird immer dann aufgerufen, wenn die akzeptierte Maustaste gedrückt wurde, wobei die linke Maustaste der Standardwert ist. Wir können Aktionen mit dem onClicked Handler verknüpfen. In unserem Beispiel gibt console.log() Text aus immer dann, wenn innerhalb der MouseArea geklickt wird. Die Funktion console.log() ist ein nützliches Werkzeug zur Fehlersuche und zur Ausgabe von Text.

Der Quelltext in SimpleButton.qml ist ausreichend um einen Schalter auf dem Bildschirm anzuzeigen und Text auszugeben, wenn auf den Schalter geklickt wird.

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 vollständig funktionsfähiger Schalter finden Sie in Button.qml. Die Quelltextbeispiele in diesem Artikel lassen einen Teil des Codes aus, angezeigt durch die …, entweder weil sie bereits in einem früheren Beispiel eingeführt wurden oder in dem aktuell besprochenen Quelltextabschnitt irrelevant sind.

Benutzerdefinierte Eigenschaften werden mit der property type name Syntax deklariert. Im Beispielcode wird, die Eigenschaft buttonColor, vom Typ color, deklariert und bekommt den Wert "lightblue" zugewiesen. Die Eigenschaft buttonColor wird später in einer bedingten Operation benutzt um die Füllfarbe des Schalters zu bestimmen. Beachten Sie, dass die Wertzuweisung einer Eigenschaft mit dem = Gleichheitszeichen gemacht wird, im Gegensatz zur Wertzuweisung mit dem Doppelpunkt. Benutzerdefinierte Eigenschaften erlauben es, dass auf interne Elemente auch außerhalb des Geltungsbereichs des Rechtecks zugegriffen werden kann. Es gibt QML-Basis-Typen wie z.B. int, string, real als auch einen allgemeinen Typ namens variant.

Durch Verbinden der beiden Signal-Handler onEntered und onExited mit Farben wird der Rahmen des Schalters gelb, wenn sich die Maus über dem Schalter befindet und ändert die Farbe wieder zurück, wenn die Maus den Bereich des Schalters verlässt.

Ein buttonClick() Signal wurde in Button.qml deklariert, indem das Schlüsselwort signal vor den Signalnamen gesetzt wurde. Alle Signale haben eigene Handler, die automatisch erzeugt werden und deren Namen mit on beginnen. Das führt dazu, dass der buttonClick-Handler onButtonClick heißt. onButtonClick wird dann eine Aktion zugewiesen. In unserem Schalter-Beispiel ruft der onClicked Maus-Handler einfach die Funktion onButtonClick auf, die einen Text anzeigt. Die Funktion onButtonClick erlaubt außenstehenden Objekten einen einfachen Zugriff auf den Maus-Bereich des Schalters. Ein Beispiel: Elemente können mehrere Maus-Empfindliche-Bereiche besitzen und ein buttonClick-Signal kann dann zwischen den einzelnen Bereichen unterscheiden.

Wir haben nur das grundlegende Wissen wie in QML-Elemente implementiert werden, die einfache Maus-Bewegungen behandeln können. Wir haben ein Text-Feld innerhalb eines Rechtecks erzeugt, seine Eigenschaften verändert und haben das Verhalten in Bezug auf Maus-Bewegungen implementiert. Die Idee Elemente innerhalb von Elementen zu erzeugen, wird sich in der ganzen Text-Editor-Anwendung wiederholen.

Dieser Schalter ist nicht sinnvoll, solange er nicht als Komponente genutzt wird, um eine Aktion auszulösen. Im nächsten Abschnitt werden wir ein Menü erzeugen, dass aus mehreren dieser Schalter bestehen wird.

Schalter

Erzeugen einer Menu-Seite

Bis zu diesem Punkt haben wir gezeigt, wie Elemente und ihr zugehöriges Verhalten innerhalb einer einzigen QML-Datei erzeugt werden können. In diesem Abschnitt zeigen, wie QML-Elemente importiert werden und wie man Komponenten wiederverwenden kann, um andere Komponenten zu erstellen. Menus zeigen den Inhalt einer Liste an, jedes Element dieser Liste kann eine Aktion ausführen. In QML erzeugen wir ein Menu auf verschiedene Arten. Zuerst erzeugen wir ein Menu, das aus mehreren Schaltern bestehen wird, das dann schließlich verschiedene Aktionen ausführen wird. Der Quelltext für dieses Menu befindet sich in FileMenu.qml

 import QtQuick 1.0 //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 erklärt wie man das Schlüsselwort import verwendet. Dieses wird benötigt um JavaScript- oder QML-Dateien zu verwenden, die sich nicht im gleichen Verzeichnis befinden. Da sich die Datei Button.qml im gleichen Verzeichnis wie FileMenu.qml befindet brauchen wir nicht import um diese Datei zu verwenden. Wir können direkt den Schalter verwenden in dem wir ihn mittels Button{} deklarieren, ähnlich wie wir Rectangle{} deklariert haben.

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 der Datei FileMenu.qml deklarieren wir drei Schalter-Elemente. Diese werden innerhalb eines Zeilen-Elements deklariert, das seine Kinder vertikal anordnet. Die Deklaration des Schalters befindet sich in der Datei Button.qml, dabei handelt es sich um die gleiche Datei, die wir bereits im letzten Abschnitt verwendet haben. Neue Eigenschaftsverbindungen können innerhalb des neu erzeugten Schalters definiert werden. Dadurch werden die Eigenschaften aus der Datei Button.qml überschrieben. Der Schalter exitButton wird die Anwendung beenden und das Fenster schließen, sobald er angeklickt wird. Beachten Sie, dass der Signal-Handler onButtonClicked in Button.qml zusätzlich zu dem Handler onButtonClicked des exitButton aufgerufen wird.

Datei-Menu

Die Zeilen Deklaration erfolgt innerhalb von Rectangle und erzeugt einen rechteckigen Container für eine Zeile mit Schaltern. Dieses zusätliche Rechteck erzeugt eine Indirektion um eine Zeile von Schaltern innerhalb eines Menus zu organisieren.

Die Deklaration des Bearbeiten-Menu ist sehr ähnlich. Das Menu beinhaltet Schalter und diese sind beschriftet: Copy, Paste und Select All.

Bearbeiten-Menu

Ausgerüstet mit unserem Wissen über das Importieren und Anpassen von bestehenden Komponenten, können wir nun die Menü Seiten kombinieren um eine Menü Zeile, bestehend aus Schaltern, um Menus auszuwählen, erstellen. Und wir sehen uns an wie wir Daten mit Hilfe von QML strukturieren können.