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.