Sur cette page

Liaison de propriété

Une propriété d'un objet peut se voir attribuer une valeur statique qui reste constante jusqu'à ce qu'une nouvelle valeur lui soit explicitement attribuée. Cependant, pour tirer le meilleur parti de QML et de sa prise en charge intégrée des comportements dynamiques des objets, la plupart des objets QML utilisent des liaisons de propriété.

Les liaisons de propriétés sont une caractéristique essentielle de QML qui permet aux développeurs de spécifier les relations entre les différentes propriétés d'un objet. Lorsque les dépendances d' une propriété changent de valeur, la propriété est automatiquement mise à jour en fonction de la relation spécifiée.

En coulisses, le moteur QML surveille les dépendances de la propriété (c'est-à-dire les variables de l'expression de liaison). Lorsqu'un changement est détecté, le moteur QML réévalue l'expression de liaison et applique le nouveau résultat à la propriété.

Vue d'ensemble

Pour créer une liaison de propriété, on attribue à une propriété une expression JavaScript qui s'évalue à la valeur souhaitée. Dans sa forme la plus simple, une liaison peut être une référence à une autre propriété. Prenons l'exemple suivant, dans lequel la hauteur du Rectangle bleu est liée à la hauteur de son parent :

Rectangle {
    width: 200; height: 200

    Rectangle {
        width: 100
        height: parent.height
        color: "blue"
    }
}

Lorsque la hauteur du rectangle parent change, la hauteur du rectangle bleu est automatiquement mise à jour pour prendre la même valeur.

Une liaison peut contenir n'importe quelle expression ou instruction JavaScript valide, car QML utilise un moteur JavaScript conforme aux normes. Les liaisons peuvent accéder aux propriétés des objets, appeler des méthodes et utiliser des objets JavaScript intégrés tels que Date et Math. Vous trouverez ci-dessous d'autres liaisons possibles pour l'exemple précédent :

height: parent.height / 2

height: Math.min(parent.width, parent.height)

height: parent.height > 100 ? parent.height : parent.height/2

height: {
    if (parent.height > 100)
        return parent.height
    else
        return parent.height / 2
}

height: someMethodThatReturnsHeight()

Voici un exemple plus complexe impliquant davantage d'objets et de types :

Column {
    id: column
    width: 200
    height: 200

    Rectangle {
        id: topRect
        width: Math.max(bottomRect.width, parent.width/2)
        height: (parent.height / 3) + 10
        color: "yellow"

        TextInput {
            id: myTextInput
            text: "Hello QML!"
        }
    }

    Rectangle {
        id: bottomRect
        width: 100
        height: 50
        color: myTextInput.text.length <= 10 ? "red" : "blue"
    }
}

Dans l'exemple précédent,

  • topRect.width dépend de bottomRect.width et column.width
  • topRect.height dépend de column.height
  • bottomRect.color dépend de myTextInput.text.length

En outre, toutes les propriétés référencées dans une fonction JavaScript qui est elle-même utilisée comme liaison seront réévaluées. Par exemple, dans l'extrait ci-dessous, chaque fois que la propriété enabled de Rectangle change, les liaisons pour les propriétés x et y sont réévaluées :

Rectangle {
    x: rectPosition()
    y: rectPosition()
    width: 200
    height: 200
    color: "lightblue"

    function rectPosition() {
        return enabled ? 0 : 100
    }
}

D'un point de vue syntaxique, les liaisons peuvent être d'une complexité arbitraire. Toutefois, si une liaison est excessivement complexe, par exemple si elle implique plusieurs lignes ou des boucles impératives, cela peut indiquer que la liaison est utilisée pour autre chose que la description des relations entre les propriétés. Les liaisons complexes peuvent réduire les performances, la lisibilité et la maintenabilité du code. Il peut être judicieux de revoir la conception des composants qui ont des liaisons complexes, ou au moins d'intégrer la liaison dans une fonction distincte. En règle générale, les utilisateurs ne doivent pas se fier à l'ordre d'évaluation des liaisons.

Création de liaisons de propriétés à partir de JavaScript

Une propriété avec une liaison est automatiquement mise à jour si nécessaire. Toutefois, si une valeur statique est attribuée ultérieurement à la propriété à partir d'une instruction JavaScript, la liaison sera supprimée.

Par exemple, le Rectangle ci-dessous garantit initialement que son height est toujours le double de son width. Toutefois, lorsque l'on appuie sur la touche espace, la valeur actuelle de width*3 est attribuée à height en tant que valeur statique. Par la suite, height restera fixé à cette valeur, même si width change. L'attribution de la valeur statique supprime la liaison.

import QtQuick 2.0

Rectangle {
    width: 100
    height: width * 2

    focus: true
    Keys.onSpacePressed: {
        height = width * 3
    }
}

Si l'intention est de donner au rectangle une hauteur fixe et d'arrêter les mises à jour automatiques, cela ne pose pas de problème. Toutefois, si l'intention est d'établir une nouvelle relation entre width et height, la nouvelle expression de liaison doit être enveloppée dans la fonction Qt.binding() :

import QtQuick 2.0

Rectangle {
    width: 100
    height: width * 2

    focus: true
    Keys.onSpacePressed: {
        height = Qt.binding(function() { return width * 3 })
    }
}

Maintenant, après avoir appuyé sur la touche espace, la hauteur du rectangle continuera à se mettre à jour automatiquement pour être toujours égale à trois fois sa largeur.

Débogage de l'écrasement des liaisons

Une cause fréquente de bogues dans les applications QML est l'écrasement accidentel des liaisons avec des valeurs statiques provenant d'instructions JavaScript. Pour aider les développeurs à repérer les problèmes de ce type, le moteur QML est capable d'émettre des messages chaque fois qu'une liaison est perdue en raison d'affectations impératives.

Afin de générer de tels messages, vous devez activer la sortie informationnelle pour la catégorie de journalisation qt.qml.binding.removal, par exemple en appelant :

QLoggingCategory::setFilterRules(QStringLiteral("qt.qml.binding.removal.info=true"));

Veuillez vous référer à la documentation de QLoggingCategory pour plus d'informations sur l'activation de la sortie des catégories de journalisation.

Notez qu'il est tout à fait raisonnable, dans certaines circonstances, d'écraser les liaisons. Tout message généré par le moteur QML doit être considéré comme une aide au diagnostic, et pas nécessairement comme la preuve d'un problème sans une investigation plus poussée.

Utilisation de this avec Property Binding

Lors de la création d'une liaison de propriété à partir de JavaScript, le mot-clé this peut être utilisé pour faire référence à l'objet qui reçoit la liaison. Cela permet de résoudre les ambiguïtés liées aux noms des propriétés.

Par exemple, le gestionnaire Component.onCompleted ci-dessous est défini dans la portée de l'objet Item. Dans cette portée, width fait référence à la largeur de l'objet Item et non à celle de l'objet Rectangle. Pour lier le height de Rectangle à son propre width, l'expression de liaison doit explicitement faire référence à this.width (ou alternativement à rect.width) :

Item {
    width: 500
    height: 500

    Rectangle {
        id: rect
        width: 100
        color: "yellow"
    }

    Component.onCompleted: {
        rect.height = Qt.binding(function() { return this.width * 2 })
        console.log("rect.height = " + rect.height) // prints 200, not 1000
    }
}

Remarque : la valeur de this n'est pas définie en dehors des liaisons de propriétés. Voir les restrictions de l'environnement JavaScript pour plus de détails.

Voir aussi Positionnement avec des ancres.

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