Sur cette page

Définition des types d'objets à l'aide de documents QML

L'une des principales caractéristiques de QML est qu'il permet de définir facilement des types d'objets QML de manière légère par le biais de documents QML afin de répondre aux besoins des applications QML individuelles. Le module standard Qt Quick fournit divers types tels que Rectangle, Text et Image pour construire une application QML ; au-delà de ces types, vous pouvez facilement définir vos propres types QML à réutiliser dans votre application. Cette capacité à créer vos propres types constitue les éléments de base de toute application QML.

Définition d'un type d'objet avec un fichier QML

Nommer les types d'objets QML personnalisés

Pour créer un type d'objet, un document QML doit être placé dans un fichier texte nommé <NomDeType>.qml<NomDeType> est le nom souhaité pour le type. Le nom du type doit répondre aux exigences suivantes :

  • Il doit être composé de caractères alphanumériques ou de traits de soulignement.
  • Il doit commencer par une lettre majuscule.

Ce document est alors automatiquement reconnu par le moteur comme une définition d'un type QML. En outre, un type défini de cette manière est automatiquement mis à la disposition d'autres fichiers QML dans le même répertoire local, car le moteur effectue une recherche dans le répertoire immédiat lorsqu'il résout les noms de types QML.

Remarque : le moteur QML ne recherche pas automatiquement les répertoires distants de cette manière. Vous devez ajouter un fichier qmldir si vos documents sont chargés sur le réseau. Voir Importer des répertoires de documents QML.

Définition d'un type QML personnalisé

Par exemple, voici un document qui déclare un Rectangle avec un enfant MouseArea. Le document a été enregistré dans un fichier nommé SquareButton.qml:

// 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!")
    }
}

Puisque le fichier est nommé SquareButton.qml, il peut maintenant être utilisé comme un type nommé SquareButton par tout autre fichier QML dans le même répertoire. Par exemple, s'il y avait un fichier myapplication.qml dans le même répertoire, il pourrait faire référence au type SquareButton:

// myapplication.qml
import QtQuick 2.0

SquareButton {}

Le type de bouton carré dans myapplication.qml hérite des propriétés définies dans SquareButton.qml.

Cela crée un document rouge de 100 x 100 Rectangle avec un document intérieur MouseArea, tel que défini dans SquareButton.qml. Lorsque ce document myapplication.qml est chargé par le moteur, il charge le document SquareButton.qml en tant que composant et l'instancie pour créer un objet SquareButton.

Le type SquareButton encapsule l'arbre des objets QML déclarés dans SquareButton.qml. Lorsque le moteur QML instancie un objet SquareButton à partir de ce type, il instancie un objet de l'arbre Rectangle déclaré dans SquareButton.qml.

Remarque : la casse du nom de fichier est importante dans certains systèmes de fichiers (notamment UNIX). Il est recommandé que la casse du nom de fichier corresponde exactement à celle du nom du type QML souhaité - par exemple, Box.qml et non BoX.qml - quelle que soit la plate-forme sur laquelle le type QML sera déployé.

Composants en ligne

Il est parfois peu pratique de créer un nouveau fichier pour un type, par exemple lorsqu'on réutilise un petit délégué dans plusieurs vues. Si vous n'avez pas besoin d'exposer le type, mais seulement de créer une instance, Component est une option. Mais si vous voulez déclarer des propriétés avec les types de composants, ou si vous voulez les utiliser dans plusieurs fichiers, Component n'est pas une option. Dans ce cas, vous pouvez utiliser les composants en ligne. Les composants inline déclarent un nouveau composant à l'intérieur d'un fichier. La syntaxe est la suivante

component <component name> : BaseType {
    // declare properties and bindings here
}

Dans le fichier qui déclare le composant inline, le type peut être référencé simplement par son nom.

// 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
}

Dans les autres fichiers, il doit être préfixé par le nom du composant qui le contient.

// 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
    }
}

Remarque : les composants inline ne partagent pas leur portée avec le composant dans lequel ils sont déclarés. Dans l'exemple suivant, lorsque A.MyInlineComponent est créé dans le fichier B.qml, une erreur de référence (ReferenceError) se produit, car root n'existe pas en tant qu'identifiant dans B.qml. Il est donc conseillé de ne pas référencer dans un composant inline des objets qui n'en font pas partie.

// 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 {}
}

Remarque : les composants en ligne ne peuvent pas être imbriqués.

Importation de types définis en dehors du répertoire actuel

Si SquareButton.qml ne se trouvait pas dans le même répertoire que myapplication.qml, le type SquareButton devrait être spécifiquement rendu disponible par une instruction d'importation dans myapplication.qml. Il pourrait être importé à partir d'un chemin relatif sur le système de fichiers, ou en tant que module installé ; voir module pour plus de détails.

Attributs accessibles des types personnalisés

La définition de l'objet racine d'un fichier .qml définit les attributs disponibles pour un type QML. Toutes les propriétés, tous les signaux et toutes les méthodes qui appartiennent à cet objet racine - qu'ils soient déclarés de manière personnalisée ou qu'ils proviennent du type QML de l'objet racine - sont accessibles de l'extérieur et peuvent être lus et modifiés pour les objets de ce type.

Par exemple, le type d'objet racine dans le fichier SquareButton.qml ci-dessus est Rectangle. Cela signifie que toutes les propriétés définies par le type Rectangle peuvent être modifiées pour un objet SquareButton. Le code ci-dessous définit trois objets SquareButton avec des valeurs personnalisées pour certaines des propriétés de l'objet racine Rectangle de type SquareButton:

// application.qml
import QtQuick 2.0

Column {
    SquareButton { side: 50 }
    SquareButton { x: 50; color: "blue" }
    SquareButton { radius: 10 }
}

Colonne contenant trois boutons carrés avec des propriétés de couleur et de taille différentes

Les attributs accessibles aux objets du type QML personnalisé comprennent toutes les propriétés, méthodes et signaux personnalisés qui ont été définis pour un objet. Par exemple, supposons que l'objet Rectangle de SquareButton.qml ait été défini comme suit, avec des propriétés, des méthodes et des signaux supplémentaires :

// 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)
    }
}

Tout objet SquareButton peut utiliser la propriété pressed, le signal buttonClicked et la méthode randomizeColor() qui ont été ajoutés à la racine Rectangle:

// application.qml
import QtQuick 2.0

SquareButton {
    id: squareButton

    onButtonClicked: (xPos, yPos)=> {
        console.log("Clicked", xPos, yPos)
        randomizeColor()
    }

    Text { text: squareButton.pressed ? "Down" : "Up" }
}

Notez que les valeurs de id définies dans SquareButton.qml ne sont pas accessibles aux objets SquareButton, car les valeurs d'identification ne sont accessibles qu'à l'intérieur de la portée du composant dans lequel un composant est déclaré. La définition de l'objet SquareButton ci-dessus ne peut pas faire référence à mouseArea pour faire référence à l'enfant MouseArea, et si elle avait un id de root au lieu de squareButton, cela n'entrerait pas en conflit avec le id de la même valeur pour l'objet racine défini dans SquareButton.qml car les deux seraient déclarés dans des portées distinctes.

© 2026 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.