Quick Start QML Programming/de: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
(Add "cleanup" tag)
(→‎Knopf und Menü definieren: Einzeiler in Text integriert, fuer die Lesbarkeit...)
 
(3 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Cleanup | reason=Auto-imported from ExpressionEngine.}}
{{Cleanup | reason=Auto-imported from ExpressionEngine.}}


[toc align_right="yes" depth="2"]


= Schnelleinstieg in die Programmierung mit QML =
= Schnelleinstieg in die Programmierung mit QML =
Line 9: Line 8:
== QML um Benutzerschnittstellen 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.
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 [http://doc.qt.nokia.com/4.7/metaobjects.html Qts Meta-Object System] 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=. [[Image:http://doc.qt.nokia.com/4.7/images/qml-texteditor5_editmenu.png|Texteditor]]
p=. [[Image:http://doc.qt.nokia.com/4.7/images/qml-texteditor5_editmenu.png|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.
Um das QML Beispiel auszuführen reicht es dem [http://doc.qt.nokia.com/4.7/qmlviewer.html qmlviewer] die QML Datei als Argument zu übergeben. Der C++ Teil dieser Anleitung setzt grundlegendes Wissen um den Qts Kompilierungsprozess voraus.


== Knopf und Menü definieren ==
== Knopf und Menü definieren ==
Line 21: Line 20:
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.
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 <code>Rectangle</code> Element hat Eigenschaften zu Kontrolle des Aussehens und Position.
In QML ist das [http://doc.qt.nokia.com/4.7/qml-rectangle.html Rechteck] das grundlegende visuelle Element. Das ''Rectangle'' Element hat Eigenschaften zu Kontrolle des Aussehens und Position.
<code>import Qt 4.7
<code>
import Qt 4.7


Rectangle{
Rectangle{
Line 35: Line 35:
  anchors.verticalCenterOffset: –1
  anchors.verticalCenterOffset: –1
  }
  }
}</code>
}
Zunächst erlaubt <code>import Qt 4.7</code> 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.
</code>
Zunächst erlaubt ''import Qt 4.7'' dem qmlviewer QML Elemente zu importieren, die wir später verwenden werden. Diese Zeile muss 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, <code>simplebutton</code>, der an die <code>id</code> Eigentschaft gebunden ist. <code>Rectangle</code>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 <code>width</code> und Höhe <code>height</code> des Rechteckes.
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 <code>buttonLabel</code>. Um den Textinhalt des Textfeldes zu setzen binden wir die <code>text</code>-Eigenschaft an einen Wert. Die Beschriftung ist im Rechteck Element enthalten und wird innerhalb des Elternelements zentriert in dem wir die Anker (<code>anchors</code>) Eigenschaft des Textelementes dem Elternelement zuweisen — <code>simplebutton</code>. Anker können auch an Anker anderer Elemente gebunden werden, um Layoutzuweisungen zu erleichtern.
Das [http://doc.qt.nokia.com/4.7/qml-text.html Textelement] 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 <code>SimpleButton.qml</code> abspeichern. Das Ausführen von qmlviewer mit dieser Datei als Argument zeigt uns das graue Rechteck mit einer Textuellen Bezeichnung.
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=. [[Image:http://doc.qt.nokia.com/4.7/images/qml-texteditor1_simplebutton.png|Einfacher Knopf]]
p=. [[Image:http://doc.qt.nokia.com/4.7/images/qml-texteditor1_simplebutton.png|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.
Um die Klickfunktionalität des Knopfes zu implementieren, greifen wir auf QMLs Ereignisbehandlung zurück. QMLs Ereignisbehandlung ist dem [http://doc.qt.nokia.com/4.7/signalsandslots.html Qt's signal and slot] Mechanismus sehr ähnlich. Signale werden ausgelöst und damit verbundene Slots werden aufgerufen.
<code>Rectangle{
<code>Rectangle{
  id:simplebutton
  id:simplebutton
Line 59: Line 60:
  }
  }
}</code>
}</code>
Wir fügen ein "MouseArea":http://doc.qt.nokia.com/4.7/qml-mousearea.html Element in unseren <code>simplebutton</code> ein. <code>MouseArea</code> 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 — <code>simplebutton</code>. Die <code>anchors.fill</code> Syntax ist ein Weg um an die <code>fill</code> 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.
Wir fügen ein [http://doc.qt.nokia.com/4.7/qml-mousearea.html MouseArea] Element in unseren ''simplebutton'' ein. ''MouseArea'' Elemente beschreiben den interaktiven Bereich in dem Mausbewegungen registriert werden. Bei unserem Knopf verankern wir den gesamten [http://doc.qt.nokia.com/4.7/qml-mousearea.html MouseArea] 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 [http://doc.qt.nokia.com/4.7/qml-anchor-layout.html Ankerbasierte Layouts] an Stellen wo Elemente an andere Elemente ankern können um robuste Layouts zu ermöglichen.


Die <code>MouseArea</code> hat viele Signalbehandlungsroutinen, die während einer Mausbewegung aufgerufen werden, die innerhalb der angegebenen <code>MouseArea</code> auftreten. Eine davon ist <code>onClicked</code>. Diese wird immer dann aufgerufen, wenn akzeptierter Mausknopf gedrückt wird; Linksklick ist dabei der Standard. Wir können mit der <code>onClicked</code> Routine Aktionen verbinden. In unserem Beispiel gibt <code>console.log()</code> einen Text aus bei jedem Klick in die MouseArea. Die Funktion <code>console.log()</code> ist eine nützliche Funktion um Funktionalitäten auszutesten oder einen Text auszugeben.
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 <code>SimpleButton.qml</code> genügt um einen Knopf anzuzeigen und einen Text für jeden getätigten Klick auszugeben.
Der Code in ''SimpleButton.qml'' genügt um einen Knopf anzuzeigen und einen Text für jeden getätigten Klick auszugeben.
<code>Rectangle {
<code>Rectangle {
  id:Button
  id:Button
Line 87: Line 88:
  color: buttonMouseArea.pressed ? Qt.darker(buttonColor, 1.5) : buttonColor
  color: buttonMouseArea.pressed ? Qt.darker(buttonColor, 1.5) : buttonColor
}</code>
}</code>
Ein voll funktioneller Knopf ist in <code>Button.qml</code>. Der Codeschnipsel in diesem Artikel läßt Codestücke, die bereits erklärt wurden, weg.
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 <code>property typ name</code> Syntax definiert. Im code wird die Eigenschaft <code>buttonColor</code> mit dem typ <code>color</code> deklariert und an den Wert <code>"lightblue"</code> gebunden. Die Eigenschaft <code>buttonColor</code> 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 <code>Rectangle</code> Geltungsbereich erreichbar zu machen. Es gibt grundlegende "QML Typen":http://doc.qt.nokia.com/4.7/qdeclarativebasictypes.html wie <code>int</code>, <code>string</code>, <code>real</code>, so wie <code>variant</code> genannten Typ.
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 [http://doc.qt.nokia.com/4.7/qdeclarativebasictypes.html QML Typen] wie ''int'', ''string'', ''real'', so wie ''variant'' genannten Typ.


Durch die Anbindung der <code>onEntered</code> und <code>onExited</code> 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.
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 <code>buttonClicked()</code> Signal wird in <code>Button.qml</code> durch das Platzieren des <code>signal</code> Schlüsselwortes vor dem Signalnamen deklariert. Alle Signale bekommen ihre Signalroutine automatisch, ihren Namen mit <code>on</code> beginnend, generiert. Als Ergebnis ist <code>onButtonClick</code> <code>buttonClick</code>s Signalroutine. <code>onButtonClick</code> wird dann eine auszuführende Aktion zugewiesen. In unserem Knopf Beispiel ruft die <code>onClicked</code> Signalroutine einfach <code>onButtonClick</code> auf, die einen Text anzeigt. Die <code>onButtonClick</code> Routine ermöglicht externen Objekten einfachen Zugrif auf den Mausbereich. Zum Beispiel können Gegenstände mehrere <code>MouseArea</code> Deklarationen besitzen und ein <code>buttonClick</code> Signal macht die Unterscheidung zwischen den verschiedenen <code>MouseArea</code> Signalroutinen einfacher.
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 <code>Rectangle</code> 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.
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.
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.
Line 111: Line 112:
import "script.js" as Script import a Javascript file and name it as Script
import "script.js" as Script import a Javascript file and name it as Script
</code>
</code>
Die oben gezeigte Syntax zeigt, wie das <code>import</code> 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 <code>Button.qml</code> im selben Verzeichnis liegt wie <code>FileMenu.qml</code>, brauchen wir <code>Button.qml</code> nicht zu importieren um es verwenden zu können. Wir können direkt ein <code>Button</code> Element erstellen durch die Deklaration <code>Button{}</code>, ähnlich der <code>Rectangle{}</code> Deklaration.
Die oben gezeigte Syntax zeigt, wie das <code>import</code> Schlüsselwort zu benutzen ist. Dieses ist nötig um [https://developer.mozilla.org/de/JavaScript JavaScript] Dateien verwenden zu können, oder QML Dateien, die nicht im gleichen Verzeichnis liegen. Da <code>Button.qml</code> im selben Verzeichnis liegt wie <code>FileMenu.qml</code>, brauchen wir <code>Button.qml</code> nicht zu importieren um es verwenden zu können. Wir können direkt ein <code>Button</code> Element erstellen durch die Deklaration <code>Button{}</code>, ähnlich der <code>Rectangle{}</code> Deklaration.
<code>
<code>
In FileMenu.qml:
In FileMenu.qml:
Line 138: Line 139:
  }
  }
</code>
</code>
In <code>FileMenu.qml</code> deklarieren wir drei <code>Button</code> 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 <code>Button</code> 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 <code>exitButton</code> genannte Knopf beendet und schließt das Anwendungsfenster beim Klicken. Beachten Sie, daß die Signalroutine <code>onButtonClick</code> in <code>Button.qml</code> zusätzlich zu <code>onButtonClick</code> Routine im <code>exitButton</code> aufgerufen wird.
In <code>FileMenu.qml</code> deklarieren wir drei <code>Button</code> Elemente. Sie werden innerhalb eines [http://doc.qt.nokia.com/4.7/qml-row.html Row] Elementes deklariert, einem Stellungregler, der seine Kinder vertikal ausrichtet. Die <code>Button</code> 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 <code>exitButton</code> genannte Knopf beendet und schließt das Anwendungsfenster beim Klicken. Beachten Sie, daß die Signalroutine <code>onButtonClick</code> in <code>Button.qml</code> zusätzlich zu <code>onButtonClick</code> Routine im <code>exitButton</code> aufgerufen wird.


p=. [[Image:http://doc.qt.nokia.com/4.7/images/qml-texteditor1_filemenu.png|Menü]]
p=. [[Image:http://doc.qt.nokia.com/4.7/images/qml-texteditor1_filemenu.png|Menü]]
Line 156: Line 157:
== Datenmodelle und Ansichten benutzen ==
== 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 <code>VisualItemModel</code> deklariert. Das "VisualItemModel":http://doc.qt.nokia.com/4.7/qml-visualitemmodel.html Element beinhaltet Elemente, die bereits Ansichten besitzen, wie die <code>Rectangle</code> 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.
QML hat unterschiedliche [http://doc.qt.nokia.com/4.7/qdeclarativemodels.html Datenansichten], 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 <code>VisualItemModel</code> deklariert. Das [http://doc.qt.nokia.com/4.7/qml-visualitemmodel.html VisualItemModel] Element beinhaltet Elemente, die bereits Ansichten besitzen, wie die <code>Rectangle</code> Elemente und importierte UI Elemente. Andere Modelltypen wie das [http://doc.qt.nokia.com/4.7/qml-listmodel.html ListModel] Element brauchen einen Delegierer um ihre Daten anzuzeigen.


Wir deklarieren zwei visuelle Dinge in <code>menuListModel</code>, das <code>FileMenu</code> und das <code>EditMenu</code>. 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 <code>MenuBar.qml</code> Datei beinhaltet die QML Deklarationen und ein einfaches <code>edit</code> Menü ist in der <code>EditMenu.qml</code> definiert.
Wir deklarieren zwei visuelle Dinge in <code>menuListModel</code>, das <code>FileMenu</code> und das <code>EditMenu</code>. Wir passen die zwei Menüs an und zeigen sie an unter Verwendung von einem [http://doc.qt.nokia.com/4.7/qml-listview.html ListView]. Die <code>MenuBar.qml</code> Datei beinhaltet die QML Deklarationen und ein einfaches <code>edit</code> Menü ist in der <code>EditMenu.qml</code> definiert.
<code>VisualItemModel {
<code>VisualItemModel {
  id: menuListModel
  id: menuListModel
Line 173: Line 174:
}
}
</code>
</code>
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 <code>menuListModel</code> hat bereits sichtbare Dinge, deshalb brauchen wir keinen Delegierer zu deklarieren.
Das [http://doc.qt.nokia.com/4.7/qml-listview.html ListView] 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 <code>menuListModel</code> hat bereits sichtbare Dinge, deshalb brauchen wir keinen Delegierer zu deklarieren.
<code>ListView {
<code>ListView {
  id: menuListView
  id: menuListView
Line 196: Line 197:
}
}
</code>
</code>
Zusätzlich erbt <code>ListView</code> 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 <code>Flickable</code> Eigenschaften um das gewünschte schnellende Bewegen in unserer Ansicht zu bewirken. Speziell die Eigenschaft <code>highlightMoveDuration</code> verändert die Dauer des schnellenden Übergangs. Ein größerer <code>highlightMoveDuration</code> Wert resultiert in langsamerer Menü Umschaltung.
Zusätzlich erbt <code>ListView</code> von [http://doc.qt.nokia.com/4.7/qml-flickable.html Flickable], was die Liste auf Mausverschiebungen und andere Gesten reagieren lässt. Der letzte Teil des oberen Codes setzt <code>Flickable</code> Eigenschaften um das gewünschte schnellende Bewegen in unserer Ansicht zu bewirken. Speziell die Eigenschaft <code>highlightMoveDuration</code> verändert die Dauer des schnellenden Übergangs. Ein größerer <code>highlightMoveDuration</code> Wert resultiert in langsamerer Menü Umschaltung.


Die <code>ListView</code> 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 <code>currentIndex</code> ändert praktisch das hervorgehobene Element in der <code>ListView</code>. 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 <code>fileButton</code> Knopf ändert das aktuelle Menü zu Dateimenü, der index ist hier 0, da <code>FileMenu</code> als Erstes in der <code>menuListModel</code> deklariert ist. Ähnlich ändert der <code>editButton</code> das aktuelle Menü zu <code>EditMenu</code> wenn er geklickt wird.
Die <code>ListView</code> 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 <code>currentIndex</code> ändert praktisch das hervorgehobene Element in der <code>ListView</code>. 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 <code>fileButton</code> Knopf ändert das aktuelle Menü zu Dateimenü, der index ist hier 0, da <code>FileMenu</code> als Erstes in der <code>menuListModel</code> deklariert ist. Ähnlich ändert der <code>editButton</code> das aktuelle Menü zu <code>EditMenu</code> wenn er geklickt wird.

Latest revision as of 10:53, 5 November 2023

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.


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 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 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 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 muss 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.Rectangles 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 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 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 Element in unseren simplebutton ein. MouseArea Elemente beschreiben den interaktiven Bereich in dem Mausbewegungen registriert werden. Bei unserem Knopf verankern wir den gesamten MouseArea 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 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 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 buttonClicks 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 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 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, 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 Element beinhaltet Elemente, die bereits Ansichten besitzen, wie die

Rectangle

Elemente und importierte UI Elemente. Andere Modelltypen wie das ListModel 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. 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 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, 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

Einen Texteditor bauen

TextArea deklarieren