Definition von Objekttypen durch QML-Dokumente
Eines der Hauptmerkmale von QML besteht darin, dass QML-Objekttypen auf einfache Weise durch QML-Dokumente definiert werden können, um den Anforderungen der einzelnen QML-Anwendungen gerecht zu werden. Das Standard Qt Quick Modul bietet verschiedene Typen wie Rectangle, Text und Image für den Aufbau einer QML-Anwendung; darüber hinaus können Sie leicht Ihre eigenen QML-Typen definieren, die Sie innerhalb Ihrer Anwendung wiederverwenden können. Diese Fähigkeit, eigene Typen zu erstellen, bildet die Bausteine jeder QML-Anwendung.
Definieren eines Objekttyps mit einer QML-Datei
Benennung eigener QML-Objekttypen
Um einen Objekttyp zu erstellen, sollte ein QML-Dokument in eine Textdatei mit dem Namen <Typenname>.qml eingefügt werden, wobei <Typenname> der gewünschte Name des Typs ist. Der Name des Typs hat die folgenden Anforderungen:
- Er muss aus alphanumerischen Zeichen oder Unterstrichen bestehen.
- Er muss mit einem Großbuchstaben beginnen.
Dieses Dokument wird dann von der Engine automatisch als Definition eines QML-Typs erkannt. Außerdem wird ein auf diese Weise definierter Typ automatisch für andere QML-Dateien im selben lokalen Verzeichnis verfügbar gemacht, da die Engine bei der Auflösung von QML-Typnamen das unmittelbare Verzeichnis durchsucht.
Hinweis: Die QML-Engine durchsucht auf diese Weise nicht automatisch entfernte Verzeichnisse. Sie müssen eine qmldir-Datei hinzufügen, wenn Ihre Dokumente über das Netzwerk geladen werden. Siehe Importieren von QML-Dokumentenverzeichnissen.
Benutzerdefinierte QML-Typ-Definition
Das folgende Beispiel zeigt ein Dokument, das ein Rectangle mit einem untergeordneten MouseArea deklariert. Das Dokument wurde in einer Datei mit dem Namen SquareButton.qml
gespeichert:
// SquareButton.qml import QtQuick 2.0 Rectangle { property int side: 100 width: side; height: side color: "red" MouseArea { anchors.fill: parent onClicked: console.log("Button clicked!") } }
Da die Datei den Namen SquareButton.qml
trägt, kann sie nun von jeder anderen QML-Datei im selben Verzeichnis als Typ mit dem Namen SquareButton
verwendet werden. Befände sich beispielsweise eine Datei myapplication.qml
im selben Verzeichnis, könnte diese auf den Typ SquareButton
verweisen:
// myapplication.qml import QtQuick 2.0 SquareButton {}
Dies erzeugt ein 100 x 100 rotes Rectangle mit einem inneren MouseArea, wie in SquareButton.qml
definiert. Wenn dieses myapplication.qml
Dokument von der Engine geladen wird, lädt sie das SquareButton.qml Dokument als Komponente und instanziiert es, um ein SquareButton
Objekt zu erstellen.
Der Typ SquareButton
kapselt den Baum der in SquareButton.qml
deklarierten QML-Objekte. Wenn die QML-Engine ein SquareButton
Objekt von diesem Typ instanziiert, instanziiert sie ein Objekt aus dem Rectangle Baum, der in SquareButton.qml
deklariert ist.
Hinweis: Die Groß- und Kleinschreibung des Dateinamens ist auf einigen (vor allem UNIX-) Dateisystemen von Bedeutung. Es wird empfohlen, dass die Groß- und Kleinschreibung des Dateinamens genau mit der Groß- und Kleinschreibung des gewünschten QML-Typnamens übereinstimmt - z. B. Box.qml
und nicht BoX.qml
- unabhängig von der Plattform, auf der der QML-Typ bereitgestellt wird.
Inline-Komponenten
Manchmal kann es unpraktisch sein, eine neue Datei für einen Typ zu erstellen, z. B. wenn ein kleiner Delegat in mehreren Ansichten wiederverwendet wird. Wenn Sie den Typ nicht wirklich offenlegen müssen, sondern nur eine Instanz erstellen müssen, ist Component eine Option. Wenn Sie jedoch Eigenschaften mit den Komponententypen deklarieren wollen oder wenn Sie den Typ in mehreren Dateien verwenden wollen, ist Component
keine Option. In diesem Fall können Sie Inline-Komponenten verwenden. Inline-Komponenten deklarieren eine neue Komponente innerhalb einer Datei. Die Syntax dafür lautet
component <component name> : BaseType { // declare properties and bindings here }
Innerhalb der Datei, in der die Inline-Komponente deklariert wird, kann der Typ einfach durch seinen Namen referenziert werden.
// Images.qml import QtQuick Item { component LabeledImage: Column { property alias source: image.source property alias caption: text.text Image { id: image width: 50 height: 50 } Text { id: text font.bold: true } } Row { LabeledImage { id: before source: "before.png" caption: "Before" } LabeledImage { id: after source: "after.png" caption: "After" } } property LabeledImage selectedImage: before }
In anderen Dateien muss ihm der Name der Komponente, die ihn enthält, vorangestellt werden.
// LabeledImageBox.qml import QtQuick Rectangle { property alias caption: image.caption property alias source: image.source border.width: 2 border.color: "black" Images.LabeledImage { id: image } }
Hinweis: Inline-Komponenten teilen ihren Geltungsbereich nicht mit der Komponente, in der sie deklariert sind. Wenn im folgenden Beispiel A.MyInlineComponent
in der Datei B.qml erstellt wird, tritt ein ReferenceError auf, da root
als id in B.qml nicht existiert. Es ist daher ratsam, nicht auf Objekte in einer Inline-Komponente zu verweisen, die nicht Teil der Komponente sind.
// A.qml import QtQuick Item { id: root property string message: "From A" component MyInlineComponent : Item { Component.onCompleted: console.log(root.message) } } // B.qml import QtQuick Item { A.MyInlineComponent {} }
Hinweis: Inline-Komponenten können nicht verschachtelt werden.
Importieren von Typen, die außerhalb des aktuellen Verzeichnisses definiert sind
Befindet sich SquareButton.qml
nicht im gleichen Verzeichnis wie myapplication.qml
, muss der Typ SquareButton
durch eine Import-Anweisung in myapplication.qml
speziell verfügbar gemacht werden. Er kann von einem relativen Pfad im Dateisystem oder als installiertes Modul importiert werden; siehe Modul für weitere Einzelheiten.
Zugängliche Attribute von benutzerdefinierten Typen
Die Root-Objektdefinition in einer .qml-Datei definiert die Attribute, die für einen QML-Typ verfügbar sind. Alle Eigenschaften, Signale und Methoden, die zu diesem Stammobjekt gehören - unabhängig davon, ob sie benutzerdefiniert sind oder aus dem QML-Typ des Stammobjekts stammen - sind von außen zugänglich und können für Objekte dieses Typs gelesen und geändert werden.
Der Typ des Stammobjekts in der obigen Datei SquareButton.qml
ist zum Beispiel Rectangle. Das bedeutet, dass alle Eigenschaften, die durch den Typ Rectangle definiert sind, für ein SquareButton
Objekt geändert werden können. Der folgende Code definiert drei SquareButton
Objekte mit angepassten Werten für einige der Eigenschaften des Stammobjekts Rectangle vom Typ SquareButton
:
// application.qml import QtQuick 2.0 Column { SquareButton { side: 50 } SquareButton { x: 50; color: "blue" } SquareButton { radius: 10 } }
Zu den Attributen, auf die Objekte des benutzerdefinierten QML-Typs zugreifen können, gehören alle benutzerdefinierten Eigenschaften, Methoden und Signale, die zusätzlich für ein Objekt definiert wurden. Nehmen wir zum Beispiel an, Rectangle in SquareButton.qml
wäre wie folgt definiert worden, mit zusätzlichen Eigenschaften, Methoden und Signalen:
// SquareButton.qml import QtQuick 2.0 Rectangle { id: root property bool pressed: mouseArea.pressed signal buttonClicked(real xPos, real yPos) function randomizeColor() { root.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1) } property int side: 100 width: side; height: side color: "red" MouseArea { id: mouseArea anchors.fill: parent onClicked: (mouse)=> root.buttonClicked(mouse.x, mouse.y) } }
Jedes SquareButton
-Objekt könnte die pressed
-Eigenschaft, das buttonClicked
-Signal und die randomizeColor()
-Methode nutzen, die der Wurzel Rectangle hinzugefügt wurden:
// application.qml import QtQuick 2.0 SquareButton { id: squareButton onButtonClicked: (xPos, yPos)=> { console.log("Clicked", xPos, yPos) randomizeColor() } Text { text: squareButton.pressed ? "Down" : "Up" } }
Beachten Sie, dass alle id
Werte, die in SquareButton.qml
definiert sind, für SquareButton
Objekte nicht zugänglich sind, da id Werte nur innerhalb des Komponentenbereichs zugänglich sind, in dem eine Komponente deklariert ist. Die obige SquareButton
Objektdefinition kann nicht auf mouseArea
verweisen, um auf das MouseArea Kind zu verweisen, und wenn es einen id
von root
statt squareButton
hätte, würde dies nicht mit dem id
des gleichen Wertes für das Wurzelobjekt, das in SquareButton.qml
definiert ist, kollidieren, da die beiden in getrennten Bereichen deklariert würden.
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.