Sur cette page

Attributs des objets QML

Chaque type d'objet QML possède un ensemble défini d'attributs. Chaque instance d'un type d'objet est créée avec l'ensemble des attributs définis pour ce type d'objet. Il existe plusieurs types d'attributs qui peuvent être spécifiés et qui sont décrits ci-dessous.

Attributs dans les déclarations d'objets

Une déclaration d'objet dans un document QML définit un nouveau type. Elle déclare également une hiérarchie d'objets qui sera instanciée si une instance de ce type nouvellement défini est créée.

L'ensemble des types d'attributs des types d'objets QML est le suivant :

  • l'attribut id
  • les attributs de propriété
  • les attributs de signal
  • attributs de gestionnaire de signal
  • les attributs de méthode
  • propriétés attachées et attributs du gestionnaire de signal attaché
  • attributs d'énumération

Ces attributs sont décrits en détail ci-dessous.

L'attribut id

Un élément QML peut avoir au maximum un attribut id. Cet attribut est fourni par le langage lui-même et ne peut être redéfini ou remplacé par aucun type d'objet QML.

Une valeur peut être attribuée à l'attribut id d'une instance d'objet pour permettre à cet objet d'être identifié et référencé par d'autres objets. Cette valeur id doit commencer par une lettre minuscule ou un trait de soulignement, et ne peut contenir d'autres caractères que des lettres, des chiffres et des traits de soulignement. Il ne peut pas non plus s'agir d'un mot-clé JavaScript. Voir la spécification du langage ECMAScript pour une liste de ces mots-clés.

Si vous utilisez un nom qui ne convient pas comme identifiant JavaScript en QML, tel que as, vous ne pourrez pas faire référence à l'objet identifié en JavaScript, ce qui rendra l'identifiant pratiquement inutile. Vous pouvez néanmoins utiliser QQmlContext à partir de C++ pour interagir avec ces identifiants.

Voici un objet TextInput et un objet Text. La valeur id de l'objet TextInput est définie sur "myTextInput". L'objet Text attribue à sa propriété text la même valeur que la propriété text de l'objet TextInput, en se référant à myTextInput.text. Les deux objets afficheront alors le même texte :

import QtQuick

Column {
    width: 200; height: 200

    TextInput { id: myTextInput; text: "Hello World" }

    Text { text: myTextInput.text }
}

Il est possible de faire référence à un objet par sa valeur id à partir de n'importe quel endroit du contexte QML dans lequel il a été créé. Par conséquent, une valeur id doit toujours être unique dans son contexte. Voir Scope and Naming Resolution pour plus d'informations.

Le contexte est également exposé à C++ via la hiérarchie QQmlContext. Vous pouvez, par exemple, récupérer le contexte d'un objet spécifique via la fonction qmlContext et demander d'autres objets dans le même contexte :

QObject *textInput = qmlContext(theColumn)->objectForName("myTextInput");

Une fois qu'une instance d'objet est créée, la valeur de son attribut id ne peut être modifiée. Bien qu'il puisse ressembler à une propriété ordinaire, l'attribut id n' est pas un attribut property ordinaire, et une sémantique spéciale lui est appliquée ; par exemple, il n'est pas possible d'accéder à myTextInput.id dans l'exemple ci-dessus.

Attributs de propriété

Une propriété est un attribut d'un objet auquel on peut attribuer une valeur statique ou qui peut être lié à une expression dynamique. La valeur d'une propriété peut être lue par d'autres objets. En général, elle peut également être modifiée par un autre objet, à moins qu'un type QML particulier ne l'interdise explicitement pour une propriété spécifique.

Définition des attributs d'une propriété

Une propriété peut être définie pour un type en C++ en enregistrant une Q_PROPERTY d'une classe qui est ensuite enregistrée dans le système de type QML. Une propriété personnalisée d'un type d'objet peut également être définie dans une déclaration d'objet dans un document QML avec la syntaxe suivante :

[default] [virtual] [override] [final] [required] [readonly] property <propertyType> <propertyName>

De cette manière, une déclaration d'objet peut exposer une valeur particulière à des objets extérieurs ou maintenir un état interne plus facilement.

Les noms de propriété doivent commencer par une lettre minuscule et ne peuvent contenir que des lettres, des chiffres et des traits de soulignement. Les mots réservés de JavaScript ne sont pas des noms de propriété valides. Les mots-clés default, required, readonly, virtual, override, final sont facultatifs et modifient la sémantique de la propriété déclarée. Voir les sections suivantes sur les propriétés par défaut, les propriétés obligatoires, les propriétés en lecture seule et la sémantique de l'annulation pour plus d'informations sur leur signification respective.

La déclaration d'une propriété personnalisée crée implicitement un signal de changement de valeur pour cette propriété, ainsi qu'un gestionnaire de signal associé appelé on<PropertyName>Changed, où <PropertyName> est le nom de la propriété, avec la première lettre en majuscule.

Par exemple, la déclaration d'objet suivante définit un nouveau type dérivé du type de base Rectangle. Il possède deux nouvelles propriétés, et un gestionnaire de signal est mis en œuvre pour l'une d'entre elles :

Rectangle {
    property color previousColor
    property color nextColor
    onNextColorChanged: console.log("The next color will be: " + nextColor.toString())
}
Types valides dans les définitions de propriétés personnalisées

Tous les types de valeurs QML peuvent être utilisés comme types de propriétés personnalisées. Par exemple, voici des déclarations de propriétés valides :

Item {
    property int someNumber
    property string someString
    property url someUrl
}

(Les valeurs d'énumération sont simplement des valeurs de nombres entiers et peuvent être désignées par le type int ).

Certains types de valeurs sont fournis par le module QtQuick et ne peuvent donc pas être utilisés comme types de propriétés à moins que le module ne soit importé. Voir la documentation QML Value Types pour plus de détails.

Notez que le type de valeur var est un type générique qui peut contenir n'importe quel type de valeur, y compris des listes et des objets :

property var someNumber: 1.5
property var someString: "abc"
property var someBool: true
property var someList: [1, 2, "three", "four"]
property var someObject: Rectangle { width: 100; height: 100; color: "red" }

En outre, tout type d'objet QML peut être utilisé comme type de propriété. En outre, tout type d'objet QML peut être utilisé comme type de propriété :

property Item someItem
property Rectangle someRectangle

Ceci s'applique également aux types QML personnalisés. Si un type QML a été défini dans un fichier nommé ColorfulButton.qml (dans un répertoire qui a ensuite été importé par le client), une propriété de type ColorfulButton serait également valide.

Attribution de valeurs aux attributs des propriétés

La valeur d'une propriété d'une instance d'objet peut être spécifiée de deux manières distinctes :

  • une affectation de valeur lors de l'initialisation
  • une affectation de valeur impérative

Dans les deux cas, la valeur peut être soit une valeur statique, soit une valeur d'expression contraignante.

Attribution de valeur à l'initialisation

La syntaxe pour assigner une valeur à une propriété lors de l'initialisation est la suivante :

<propertyName> : <value>

Une affectation de valeur à l'initialisation peut être combinée avec une définition de propriété dans une déclaration d'objet, si on le souhaite. Dans ce cas, la syntaxe de la définition de la propriété devient :

[default] property <propertyType> <propertyName> : <value>

Voici un exemple d'initialisation de la valeur d'une propriété :

import QtQuick

Rectangle {
    color: "red"
    property color nextColor: "blue" // combined property declaration and initialization
}
Attribution de valeur impérative

Une affectation de valeur impérative est l'affectation d'une valeur de propriété (soit une valeur statique, soit une expression de liaison) à une propriété à partir d'un code JavaScript impératif. La syntaxe d'une affectation de valeur impérative est simplement l'opérateur d'affectation JavaScript, comme indiqué ci-dessous :

[<objectId>.]<propertyName> = value

Voici un exemple d'affectation de valeur impérative :

import QtQuick

Rectangle {
    id: rect
    Component.onCompleted: {
        rect.color = "red"
    }
}

Valeurs statiques et valeurs d'expression contraignante

Comme indiqué précédemment, deux types de valeurs peuvent être attribuées à une propriété : les valeurs statiques et les valeurs d'expression de liaison. Ces dernières sont également connues sous le nom de liaisons de propriétés.

TypeSémantique
Valeur statiqueUne valeur constante qui ne dépend pas d'autres propriétés.
Expression de liaisonUne expression JavaScript qui décrit la relation d'une propriété avec d'autres propriétés. Les variables de cette expression sont appelées les dépendances de la propriété.

Le moteur QML renforce la relation entre une propriété et ses dépendances. Lorsque l'une des dépendances change de valeur, le moteur QML réévalue automatiquement l'expression de liaison et attribue le nouveau résultat à la propriété.

Voici un exemple qui montre les deux types de valeurs attribuées aux propriétés :

import QtQuick

Rectangle {
    // both of these are static value assignments on initialization
    width: 400
    height: 200

    Rectangle {
        // both of these are binding expression value assignments on initialization
        width: parent.width / 2
        height: parent.height
    }
}

Remarque : pour affecter une expression de liaison de manière impérative, l'expression de liaison doit être contenue dans une fonction qui est transmise à Qt.binding(), puis la valeur renvoyée par Qt.binding() doit être affectée à la propriété. En revanche, Qt.binding() ne doit pas être utilisé lors de l'affectation d'une expression de liaison à l'initialisation. Voir Property Binding pour plus d'informations.

Sécurité des types

Les propriétés sont sûres quant à leur type. Une propriété ne peut se voir attribuer qu'une valeur correspondant à son type.

Par exemple, si une propriété est un int et que vous essayez de lui attribuer une chaîne de caractères, vous obtiendrez une erreur :

property int volume: "four"  // generates an error; the property's object will not be loaded

De même, si une valeur d'un type incorrect est attribuée à une propriété pendant l'exécution, la nouvelle valeur ne sera pas attribuée et une erreur sera générée.

Certains types de propriétés n'ont pas de représentation naturelle de la valeur, et pour ces types de propriétés, le moteur QML effectue automatiquement une conversion de chaîne de caractères en valeur typée. Ainsi, par exemple, même si les propriétés de type color stockent des couleurs et non des chaînes de caractères, vous pouvez affecter la chaîne "red" à une propriété de couleur, sans qu'une erreur ne soit signalée.

Voir Types de valeurs QML pour une liste des types de propriétés prises en charge par défaut. En outre, tout type d'objet QML disponible peut également être utilisé comme type de propriété.

Types de propriétés spéciales

Attributs de propriété de liste d'objets

Une propriété de type list peut se voir attribuer une liste de valeurs de type objet QML. La syntaxe pour définir une valeur de liste d'objets est une liste séparée par des virgules et entourée de crochets :

[ <item 1>, <item 2>, ... ]

Par exemple, le type Item possède une propriété states qui est utilisée pour contenir une liste d'objets de type State. Le code ci-dessous initialise la valeur de cette propriété à une liste de trois objets State:

import QtQuick

Item {
    states: [
        State { name: "loading" },
        State { name: "running" },
        State { name: "stopped" }
    ]
}

Si la liste ne contient qu'un seul élément, les crochets peuvent être omis :

import QtQuick

Item {
    states: State { name: "running" }
}

Une propriété de type list peut être spécifiée dans une déclaration d'objet avec la syntaxe suivante :

[default] property list<<ObjectType>> propertyName

et, comme pour les autres déclarations de propriétés, une initialisation de la propriété peut être combinée à la déclaration de la propriété avec la syntaxe suivante :

[default] property list<<ObjectType>> propertyName: <value>

Voici un exemple de déclaration de propriété de liste :

import QtQuick

Rectangle {
    // declaration without initialization
    property list<Rectangle> siblingRects

    // declaration with initialization
    property list<Rectangle> childRects: [
        Rectangle { color: "red" },
        Rectangle { color: "blue"}
    ]
}

Si vous souhaitez déclarer une propriété pour stocker une liste de valeurs qui ne sont pas nécessairement des valeurs de type objet QML, vous devez plutôt déclarer une propriété var.

Propriétés groupées

Dans certains cas, les propriétés contiennent un groupe logique d'attributs de sous-propriétés. Ces attributs de sous-propriété peuvent être assignés en utilisant soit la notation par points, soit la notation de groupe.

Par exemple, le type Text possède une propriété de groupe font. Ci-dessous, le premier objet Text initialise ses valeurs font en utilisant la notation par points, tandis que le second utilise la notation par groupes :

Text {
    //dot notation
    font.pixelSize: 12
    font.b: true
}

Text {
    //group notation
    font { pixelSize: 12; b: true }
}

Les types de propriétés groupées sont des types qui ont des sous-propriétés. Si un type de propriété groupée est un type d'objet (par opposition à un type de valeur), la propriété qui le contient doit être en lecture seule. Cela permet d'éviter de remplacer l'objet auquel appartiennent les sous-propriétés.

Alias de propriétés

Les alias de propriétés sont des propriétés qui contiennent une référence à une autre propriété. Contrairement à une définition de propriété ordinaire, qui alloue un nouvel espace de stockage unique pour la propriété, un alias de propriété relie la nouvelle propriété déclarée (appelée propriété d'aliasing) en tant que référence directe à une propriété existante (la propriété d'aliasing).

Une déclaration d'alias de propriété ressemble à une définition de propriété ordinaire, à ceci près qu'elle nécessite le mot-clé alias au lieu d'un type de propriété, et que le côté droit de la déclaration de propriété doit être une référence d'alias valide :

[default] property alias <name>: <alias reference>

Contrairement à une propriété ordinaire, un alias est soumis aux restrictions suivantes :

  • Il ne peut faire référence qu'à un objet, ou à la propriété d'un objet, qui se trouve dans la portée du type dans lequel l'alias est déclaré.
  • Il ne peut pas contenir d'expressions JavaScript arbitraires
  • Il ne peut pas faire référence à des objets déclarés en dehors de la portée de son type.
  • La référence de l'alias n'est pas facultative, contrairement à la valeur par défaut facultative d'une propriété ordinaire ; la référence de l'alias doit être fournie lors de la première déclaration de l'alias.
  • Elle ne peut pas faire référence à des propriétés attachées.
  • Elle ne peut pas faire référence à des propriétés situées à l'intérieur d'une hiérarchie d'une profondeur de 3 ou plus. Le code suivant ne fonctionnera pas :
    property alias color: myItem.myRect.border.color
    
    Item {
        id: myItem
        property Rectangle myRect
    }

    Cependant, les alias vers des propriétés situées jusqu'à deux niveaux de profondeur fonctionneront.

    property alias color: rectangle.border.color
    
    Rectangle {
        id: rectangle
    }

Par exemple, voici un type Button avec une propriété aliasée buttonText qui est connectée à l'objet text de l'enfant Text:

// Button.qml
import QtQuick

Rectangle {
    property alias buttonText: textItem.text

    width: 100; height: 30; color: "yellow"

    Text { id: textItem }
}

Le code suivant créerait un Button avec une chaîne de texte définie pour l'objet enfant Text:

Button { buttonText: "Click Me" }

Ici, la modification de buttonText modifie directement la valeur textItem.text ; elle ne modifie pas une autre valeur qui met ensuite à jour textItem.text. Si buttonText n'était pas un alias, la modification de sa valeur ne changerait pas du tout le texte affiché, car les liaisons de propriétés ne sont pas bidirectionnelles : la valeur de buttonText aurait changé si textItem.text avait été modifié, mais pas l'inverse.

Alias de propriétés et types

Les alias de propriétés ne peuvent pas avoir de spécification de type explicite. Le type d'un alias de propriété est le type déclaré de la propriété ou de l'objet auquel il fait référence. Par conséquent, si vous créez un alias pour un objet référencé via id avec des propriétés supplémentaires déclarées en ligne, les propriétés supplémentaires ne seront pas accessibles via l'alias :

// MyItem.qml
Item {
    property alias inner: innerItem

    Item {
        id: innerItem
        property int extraProperty
    }
}

Vous ne pouvez pas initialiser inner.extraProperty en dehors de ce composant, car inner n'est qu'un Item:

// main.qml
MyItem {
    inner.extraProperty: 5 // fails
}

Cependant, si vous extrayez l'objet interne dans un composant séparé avec un fichier .qml dédié, vous pouvez instancier ce composant à la place et avoir toutes ses propriétés disponibles à travers l'alias :

// MainItem.qml
Item {
    // Now you can access inner.extraProperty, as inner is now an ExtraItem
    property alias inner: innerItem

    ExtraItem {
        id: innerItem
    }
}

// ExtraItem.qml
Item {
    property int extraProperty
}

Propriétés par défaut

Une définition d'objet peut avoir une seule propriété par défaut. Une propriété par défaut est la propriété à laquelle une valeur est attribuée si un objet est déclaré dans la définition d'un autre objet sans qu'il soit déclaré comme valeur pour une propriété particulière.

La déclaration d'une propriété avec le mot-clé facultatif default la désigne comme propriété par défaut. Par exemple, supposons qu'il existe un fichier MyLabel.qml avec une propriété par défaut someText:

// MyLabel.qml
import QtQuick

Text {
    default property var someText

    text: `Hello, ${someText.text}`
}

La valeur someText peut être attribuée dans une définition d'objet MyLabel, comme ceci :

MyLabel {
    Text { text: "world!" }
}

Cela a exactement le même effet que ce qui suit :

MyLabel {
    someText: Text { text: "world!" }
}

Toutefois, étant donné que la propriété someText a été désignée comme propriété par défaut, il n'est pas nécessaire d'affecter explicitement l'objet Text à cette propriété.

Vous remarquerez que des objets enfants peuvent être ajoutés à n'importe quel type basé sur Item sans les ajouter explicitement à la propriété children. En effet, la propriété par défaut de Item est sa propriété data, et tout élément ajouté à cette liste pour un type Item est automatiquement ajouté à sa liste children.

Les propriétés par défaut peuvent être utiles pour réaffecter les enfants d'un élément. Par exemple, en définissant l'alias de la propriété par défaut

Item {
    default property alias content: inner.children

    Item {
        id: inner
    }
}

En définissant l'alias de la propriété par défaut à inner.children, tout objet assigné en tant qu'enfant de l'élément extérieur est automatiquement réassigné en tant qu'enfant de l'élément intérieur.

Attention : La définition des valeurs de la propriété de liste par défaut d'un élément peut être implicite ou explicite. Dans la définition d'un seul élément, ces deux méthodes ne doivent pas être mélangées car cela conduit à un ordre indéfini des éléments dans la liste.

Item {
    // Use either implicit or explicit assignement to the default list property but not both!
    Rectangle { width: 40 }            // implicit
    data: [ Rectangle { width: 100 } ] // explicit
}

Sémantique de l'override

Par défaut, les propriétés peuvent être mises à l'ombre: Vous redéclarez une propriété dans un type QML dérivé, éventuellement avec un nouveau type et de nouveaux attributs. Il en résulte deux propriétés portant le même nom, dont une seule est accessible dans un contexte donné. C'est rarement ce que l'on souhaite. C'est souvent accidentel, et la plupart du temps, les effets sont assez déroutants. En outre, le shadowing est mauvais pour l'outillage.

Pour y remédier, les mots-clés virtual, override, final et des avertissements et erreurs supplémentaires ont été introduits.

Pour plus de détails et un ensemble complet d'exemples, y compris les avertissements et les erreurs, voir la page sur l 'ombrage des propriétés et la sémantique des substitutions.

Propriétés requises

Une déclaration d'objet peut définir une propriété comme requise, en utilisant le mot-clé required. La syntaxe est la suivante

required property <propertyType> <propertyName>

Comme leur nom l'indique, les propriétés requises doivent être définies lors de la création d'une instance de l'objet. Le non-respect de cette règle entraînera le non-démarrage des applications QML s'il peut être détecté de manière statique. Dans le cas de composants QML instanciés dynamiquement (par exemple via Qt.createComponent()), la violation de cette règle entraîne un avertissement et une valeur de retour nulle.

Il est possible de rendre une propriété existante obligatoire à l'aide de la commande

required <propertyName>

L'exemple suivant montre comment créer un composant Rectangle personnalisé, dans lequel la propriété color doit toujours être spécifiée.

// ColorRectangle.qml
Rectangle {
    required color
}

Note : Vous ne pouvez pas assigner une valeur initiale à une propriété obligatoire à partir de QML, car cela irait directement à l'encontre de l'utilisation prévue des propriétés obligatoires.

Les propriétés requises jouent un rôle particulier dans le code modèle-vue-délégué : Si le délégué d'une vue possède des propriétés requises dont les noms correspondent aux noms de rôle du modèle de la vue, ces propriétés seront initialisées avec les valeurs correspondantes du modèle. Pour plus d'informations, consultez la page Modèles et vues à l' adresse Qt Quick.

Voir QQmlComponent::createWithInitialProperties, QQmlApplicationEngine::setInitialProperties et QQuickView::setInitialProperties pour les méthodes d'initialisation des propriétés requises à partir de C++.

Propriétés en lecture seule

Une déclaration d'objet peut définir une propriété en lecture seule à l'aide du mot-clé readonly, avec la syntaxe suivante :

readonly property <propertyType> <propertyName> : <value>

Les propriétés en lecture seule doivent se voir attribuer une valeur statique ou une expression de liaison lors de l'initialisation. Après l'initialisation d'une propriété en lecture seule, il n'est plus possible de modifier sa valeur statique ou son expression de liaison.

Par exemple, le code du bloc Component.onCompleted ci-dessous n'est pas valide :

Item {
    readonly property int someNumber: 10

    Component.onCompleted: someNumber = 20  // TypeError: Cannot assign to read-only property
}

Remarque : une propriété en lecture seule ne peut pas être une propriété par défaut.

Objets modificateurs de propriété

Les propriétés peuvent être associées à des objets modificateurs de valeur de propriété. La syntaxe pour déclarer une instance d'un type de modificateur de propriété associé à une propriété particulière est la suivante :

<PropertyModifierTypeName> on <propertyName> {
    // attributes of the object instance
}

Cette syntaxe est communément appelée syntaxe "on".

Il est important de noter que la syntaxe ci-dessus est en fait une déclaration d'objet qui instanciera un objet agissant sur une propriété préexistante.

Certains types de modificateurs de propriété ne peuvent s'appliquer qu'à des types de propriété spécifiques, mais cela n'est pas imposé par le langage. Par exemple, le type NumberAnimation fourni par QtQuick n'animera que les propriétés de type numérique (telles que int ou real). Une tentative d'utilisation d'un NumberAnimation avec une propriété non numérique n'entraînera pas d'erreur, mais la propriété non numérique ne sera pas animée. Le comportement d'un type de modificateur de propriété lorsqu'il est associé à un type de propriété particulier est défini par son implémentation.

Attributs des signaux

Un signal est une notification d'un objet indiquant qu'un événement s'est produit : par exemple, une propriété a changé, une animation a démarré ou s'est arrêtée, ou une image a été téléchargée. Le type MouseArea, par exemple, possède un signal clicked qui est émis lorsque l'utilisateur clique dans la zone de la souris.

Un objet peut être notifié par un gestionnaire de signal chaque fois qu'un signal particulier est émis. Un gestionnaire de signal est déclaré avec la syntaxe on<Signal><Signal> est le nom du signal, avec la première lettre en majuscule. Le gestionnaire de signal doit être déclaré dans la définition de l'objet qui émet le signal, et le gestionnaire doit contenir le bloc de code JavaScript à exécuter lorsque le gestionnaire de signal est invoqué.

Par exemple, le gestionnaire de signal onClicked ci-dessous est déclaré dans la définition de l'objet MouseArea et est invoqué lorsque l'on clique sur MouseArea, ce qui entraîne l'impression d'un message sur la console :

import QtQuick

Item {
    width: 100; height: 100

    MouseArea {
        anchors.fill: parent
        onClicked: {
            console.log("Click!")
        }
    }
}

Définition des attributs d'un signal

Un signal peut être défini pour un type en C++ en enregistrant un Q_SIGNAL d'une classe qui est ensuite enregistrée avec le système de type QML. Un signal personnalisé pour un type d'objet peut également être défini dans une déclaration d'objet dans un document QML avec la syntaxe suivante :

signal <signalName>[([<parameterName>: <parameterType>[, ...]])]

Toute tentative de déclaration de deux signaux ou méthodes portant le même nom dans le même bloc de type est une erreur. Toutefois, un nouveau signal peut réutiliser le nom d'un signal existant sur le type. (Cela doit être fait avec prudence, car le signal existant peut être caché et devenir inaccessible).

Voici trois exemples de déclarations de signaux :

import QtQuick

Item {
    signal clicked
    signal hovered()
    signal actionPerformed(action: string, actionResult: int)
}

Vous pouvez également spécifier des paramètres de signal dans une syntaxe de type propriété :

signal actionCanceled(string action)

Afin d'être cohérent avec les déclarations de méthodes, vous devriez préférer les déclarations de types utilisant des deux-points.

Si le signal n'a pas de paramètres, les crochets "()" sont facultatifs. Si des paramètres sont utilisés, les types de paramètres doivent être déclarés, comme pour les arguments string et int du signal actionPerformed ci-dessus. Les types de paramètres autorisés sont les mêmes que ceux énumérés dans la section Définition des attributs de propriété de cette page.

Pour émettre un signal, invoquez-le en tant que méthode. Tous les gestionnaires de signaux pertinents seront invoqués lorsque le signal est émis, et les gestionnaires peuvent utiliser les noms d'arguments définis pour le signal afin d'accéder aux arguments respectifs.

Signaux de changement de propriété

Les types QML fournissent également des signaux de changement de propriété intégrés qui sont émis chaque fois que la valeur d'une propriété change, comme décrit précédemment dans la section sur les attributs de propriété. Voir la section suivante sur les gestionnaires de signaux de changement de propriété pour plus d'informations sur l'utilité de ces signaux et la manière de les utiliser.

Attributs des gestionnaires de signaux

Les gestionnaires de signaux sont une sorte particulière d'attribut de méthode, où l'implémentation de la méthode est invoquée par le moteur QML chaque fois que le signal associé est émis. L'ajout d'un signal à une définition d'objet en QML ajoutera automatiquement un gestionnaire de signal associé à la définition d'objet, qui a, par défaut, une implémentation vide. Les clients peuvent fournir une implémentation pour mettre en œuvre la logique du programme.

Considérons le type SquareButton suivant, dont la définition est fournie dans le fichier SquareButton.qml comme indiqué ci-dessous, avec les signaux activated et deactivated:

// SquareButton.qml
Rectangle {
    id: root

    signal activated(xPosition: real, yPosition: real)
    signal deactivated

    property int side: 100
    width: side; height: side

    MouseArea {
        anchors.fill: parent
        onReleased: root.deactivated()
        onPressed: mouse => root.activated(mouse.x, mouse.y)
    }
}

Ces signaux peuvent être reçus par n'importe quel objet SquareButton dans un autre fichier QML dans le même répertoire, où les implémentations des gestionnaires de signaux sont fournies par le client :

// myapplication.qml
SquareButton {
    onDeactivated: console.log("Deactivated!")
    onActivated: (xPosition, yPosition) => {
        console.log(`Activated at ${xPosition}, ${yPosition}`)
    }
}

Les gestionnaires de signaux n'ont pas besoin de déclarer leurs types de paramètres car le signal les spécifie déjà. La syntaxe de la fonction flèche présentée ci-dessus ne prend pas en charge les annotations de type.

Pour plus de détails sur l'utilisation des signaux, voir le système d'événements des signaux et des gestionnaires.

Gestionnaires de signaux de changement de propriété

Les gestionnaires de signaux de changement de propriété prennent la forme syntaxique on<Property>Changed<Property> est le nom de la propriété, avec la première lettre en majuscule. Par exemple, bien que la documentation du type TextInput ne documente pas de signal textChanged, ce signal est implicitement disponible du fait que TextInput possède une propriété text et qu'il est donc possible d'écrire un gestionnaire de signal onTextChanged qui sera appelé chaque fois que cette propriété changera :

import QtQuick

TextInput {
    text: "Change this!"

    onTextChanged: console.log(`Text has changed to: ${text}`)
}

Attributs des méthodes

Une méthode d'un type d'objet est une fonction qui peut être appelée pour effectuer un traitement ou déclencher d'autres événements. Une méthode peut être connectée à un signal de sorte qu'elle soit automatiquement invoquée chaque fois que le signal est émis. Pour plus de détails, voir le système d'événements des signaux et des gestionnaires.

Définition des attributs d'une méthode

Une méthode peut être définie pour un type en C++ en étiquetant une fonction d'une classe qui est ensuite enregistrée dans le système de types QML à l'adresse Q_INVOKABLE ou en l'enregistrant en tant que Q_SLOT de la classe. Une méthode personnalisée peut également être ajoutée à une déclaration d'objet dans un document QML avec la syntaxe suivante :

function <functionName>([<parameterName>[: <parameterType>][, ...]]) [: <returnType>] { <body> }

Des méthodes peuvent être ajoutées à un type QML afin de définir des blocs de code JavaScript autonomes et réutilisables. Ces méthodes peuvent être invoquées en interne ou par des objets externes.

Contrairement aux signaux, les types de paramètres des méthodes n'ont pas besoin d'être déclarés, car ils correspondent par défaut au type var. Vous devez cependant les déclarer afin d'aider qmlcachegen à générer un code plus performant et d'améliorer la maintenabilité.

Tenter de déclarer deux méthodes ou signaux portant le même nom dans le même bloc de type est une erreur. Cependant, une nouvelle méthode peut réutiliser le nom d'une méthode existante sur le type. (Cela doit être fait avec prudence, car la méthode existante peut être cachée et devenir inaccessible).

Voici un Rectangle avec une méthode calculateHeight() qui est appelée lors de l'assignation de la valeur height:

import QtQuick
Rectangle {
    id: rect

    function calculateHeight(): real {
        return rect.width / 2;
    }

    width: 100
    height: calculateHeight()
}

Si la méthode a des paramètres, ils sont accessibles par leur nom dans la méthode. Ci-dessous, lorsque l'on clique sur MouseArea, on invoque la méthode moveTo() qui peut alors se référer aux paramètres newX et newY reçus pour repositionner le texte :

import QtQuick

Item {
    width: 200; height: 200

    MouseArea {
        anchors.fill: parent
        onClicked: mouse => label.moveTo(mouse.x, mouse.y)
    }

    Text {
        id: label

        function moveTo(newX: real, newY: real) {
            label.x = newX;
            label.y = newY;
        }

        text: "Move me!"
    }
}

Propriétés attachées et gestionnaires de signaux attachés

Lespropriétés attachées et les gestionnaires de signaux attachés sont des mécanismes qui permettent aux objets d'être annotés avec des propriétés supplémentaires ou des gestionnaires de signaux qui ne sont autrement pas disponibles pour l'objet. En particulier, ils permettent aux objets d'accéder à des propriétés ou à des signaux qui sont spécifiquement pertinents pour l'objet individuel.

Une implémentation de type QML peut choisir de créer un type d'attachement en C++ avec des propriétés et des signaux particuliers. Des instances de ce type peuvent alors être créées et attachées à des objets spécifiques au moment de l'exécution, ce qui permet à ces objets d'accéder aux propriétés et aux signaux du type d'attachement. On y accède en préfixant les propriétés et les gestionnaires de signaux respectifs par le nom du type d'attachement.

Les références aux propriétés et aux gestionnaires attachés prennent la forme syntaxique suivante :

<AttachingType>.<propertyName>
<AttachingType>.on<SignalName>

Par exemple, le type ListView possède une propriété attachée ListView.isCurrentItem qui est disponible pour chaque objet délégué dans une vue ListView. Chaque objet délégué peut l'utiliser pour déterminer s'il s'agit de l'élément actuellement sélectionné dans la vue :

import QtQuick

ListView {
    width: 240; height: 320
    model: 3
    delegate: Rectangle {
        width: 100; height: 30
        color: ListView.isCurrentItem ? "red" : "yellow"
    }
}

Dans ce cas, le nom du type d'attachement est ListView et la propriété en question est isCurrentItem, c'est pourquoi la propriété attachée est appelée ListView.isCurrentItem.

Un gestionnaire de signal attaché est désigné de la même manière. Par exemple, le gestionnaire de signal attaché Component.onCompleted est généralement utilisé pour exécuter un code JavaScript lorsque le processus de création d'un composant est terminé. Dans l'exemple ci-dessous, une fois que le composant ListModel a été entièrement créé, son gestionnaire de signal Component.onCompleted sera automatiquement invoqué pour remplir le modèle :

import QtQuick

ListView {
    width: 240; height: 320
    model: ListModel {
        id: listModel
        Component.onCompleted: {
            for (let i = 0; i < 10; i++) {
                append({ Name: `Item ${i}` })
            }
        }
    }
    delegate: Text { text: index }
}

Puisque le nom du type attaché est Component et que ce type possède un signal completed, le gestionnaire de signal attaché est appelé Component.onCompleted.

Remarque sur l'accès aux propriétés attachées et aux gestionnaires de signaux

Une erreur courante consiste à supposer que les propriétés attachées et les gestionnaires de signaux sont directement accessibles depuis les enfants de l'objet auquel ces attributs ont été attachés. Ce n'est pas le cas. L'instance du type attachant n'est attachée qu'à des objets spécifiques, et non à l'objet et à tous ses enfants.

Par exemple, voici une version modifiée de l'exemple précédent concernant les propriétés attachées. Cette fois, le délégué est un Item et le Rectangle coloré est un enfant de cet élément :

import QtQuick

ListView {
    width: 240; height: 320
    model: 3
    delegate: Item {
        width: 100; height: 30

        Rectangle {
            width: 100; height: 30
            color: ListView.isCurrentItem ? "red" : "yellow" // WRONG! This won't work.
        }
    }
}

Cela ne fonctionne pas comme prévu car ListView.isCurrentItem n' est attaché qu' à l'objet délégué racine, et non à ses enfants. Étant donné que Rectangle est un enfant du délégué, et non le délégué lui-même, il ne peut pas accéder à la propriété attachée de isCurrentItem en tant que ListView.isCurrentItem. Le rectangle doit donc accéder à isCurrentItem par l'intermédiaire du délégué racine :

ListView {
    delegate: Item {
        id: delegateItem
        width: 100; height: 30

        Rectangle {
            width: 100; height: 30
            color: delegateItem.ListView.isCurrentItem ? "red" : "yellow" // correct
        }
    }
}

Désormais, delegateItem.ListView.isCurrentItem fait correctement référence à la propriété attachée isCurrentItem du délégué.

Attributs des énumérations

Les énumérations fournissent un ensemble fixe de choix nommés. Elles peuvent être déclarées en QML à l'aide du mot-clé enum:

// MyText.qml
Text {
    enum TextType {
        Normal,
        Heading
    }
}

Comme indiqué ci-dessus, les types d'énumération (par exemple TextType) et les valeurs (par exemple Normal) doivent commencer par une lettre majuscule.

Les valeurs sont désignées par <Type>.<EnumerationType>.<Value> ou <Type>.<Value>.

// MyText.qml
Text {
    enum TextType {
        Normal,
        Heading
    }

    property int textType: MyText.TextType.Normal

    font.bold: textType === MyText.TextType.Heading
    font.pixelSize: textType === MyText.TextType.Heading ? 24 : 12
}

De plus amples informations sur l'utilisation des énumérations en QML sont disponibles dans la documentation sur les énumérations QML.

La possibilité de déclarer des énumérations en QML a été introduite dans Qt 5.10.

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