Eigenschaft Bindung

Den Eigenschaften eines Objekts kann ein statischer Wert zugewiesen werden, der konstant bleibt, bis ihm explizit ein neuer Wert zugewiesen wird. Um jedoch QML und seine integrierte Unterstützung für dynamisches Objektverhalten optimal nutzen zu können, verwenden die meisten QML-Objekte Eigenschaftsbindungen.

Eigenschaftsbindungen sind eine Kernfunktion von QML, mit der Entwickler Beziehungen zwischen verschiedenen Objekteigenschaften festlegen können. Wenn sich der Wert der Abhängigkeiten einer Eigenschaft ändert, wird die Eigenschaft automatisch entsprechend der angegebenen Beziehung aktualisiert.

Hinter den Kulissen überwacht die QML-Engine die Abhängigkeiten der Eigenschaft (d. h. die Variablen im Bindungsausdruck). Wird eine Änderung festgestellt, wertet die QML-Engine den Bindungsausdruck neu aus und wendet das neue Ergebnis auf die Eigenschaft an.

Übersicht

Um eine Eigenschaftsbindung zu erstellen, wird einer Eigenschaft ein JavaScript-Ausdruck zugewiesen, der auf den gewünschten Wert ausgewertet wird. Im einfachsten Fall kann eine Bindung ein Verweis auf eine andere Eigenschaft sein. Im folgenden Beispiel ist die Höhe des blauen Elements Rectangle an die Höhe des übergeordneten Elements gebunden:

Rectangle {
    width: 200; height: 200

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

Immer wenn sich die Höhe des übergeordneten Rechtecks ändert, wird die Höhe des blauen Rechtecks automatisch auf denselben Wert aktualisiert.

Eine Bindung kann jeden gültigen JavaScript-Ausdruck oder jede Anweisung enthalten, da QML eine standardkonforme JavaScript-Engine verwendet. Bindungen können auf Objekteigenschaften zugreifen, Methoden aufrufen und integrierte JavaScript-Objekte wie Date und Math verwenden. Nachfolgend finden Sie weitere mögliche Bindungen für das vorherige Beispiel:

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()

Im Folgenden finden Sie ein komplexeres Beispiel mit mehr Objekten und Typen:

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

Im vorherigen Beispiel,

  • topRect.width abhängig von bottomRect.width und column.width
  • topRect.height hängt ab von column.height
  • bottomRect.color hängt ab von myTextInput.text.length

Darüber hinaus werden alle Eigenschaften, auf die innerhalb einer JavaScript-Funktion verwiesen wird, die selbst als Bindung verwendet wird, neu bewertet. Wenn sich zum Beispiel im folgenden Ausschnitt die Eigenschaft enabled von Rectangle ändert, werden die Bindungen für die Eigenschaften x und y neu ausgewertet:

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

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

Syntaktisch dürfen Bindungen beliebig komplex sein. Wenn eine Bindung jedoch übermäßig komplex ist - z. B. mehrere Zeilen oder zwingende Schleifen umfasst - könnte dies darauf hindeuten, dass die Bindung für mehr als die Beschreibung von Eigenschaftsbeziehungen verwendet wird. Komplexe Bindungen können die Leistung, Lesbarkeit und Wartbarkeit des Codes beeinträchtigen. Es kann eine gute Idee sein, Komponenten mit komplexen Bindungen neu zu entwerfen oder zumindest die Bindung in eine separate Funktion auszulagern. Im Allgemeinen sollten sich die Benutzer nicht auf die Auswertungsreihenfolge von Bindungen verlassen.

Erstellen von Property-Bindings aus JavaScript

Eine Eigenschaft mit einer Bindung wird bei Bedarf automatisch aktualisiert. Wenn der Eigenschaft jedoch später ein statischer Wert aus einer JavaScript-Anweisung zugewiesen wird, wird die Bindung entfernt.

Die unten stehende Rectangle stellt beispielsweise zunächst sicher, dass height immer doppelt so groß ist wie width. Wenn jedoch die Leertaste gedrückt wird, wird der aktuelle Wert von width*3 als statischer Wert an height zugewiesen. Danach bleibt height auf diesem Wert stehen, auch wenn sich width ändert. Durch die Zuweisung des statischen Wertes wird die Bindung aufgehoben.

import QtQuick 2.0

Rectangle {
    width: 100
    height: width * 2

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

Wenn die Absicht darin besteht, dem Rechteck eine feste Höhe zu geben und automatische Aktualisierungen zu unterbinden, dann ist dies kein Problem. Wenn jedoch eine neue Beziehung zwischen width und height hergestellt werden soll, muss der neue Bindungsausdruck stattdessen in die Funktion Qt.binding() eingeschlossen werden:

import QtQuick 2.0

Rectangle {
    width: 100
    height: width * 2

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

Nachdem die Leertaste gedrückt wurde, wird die Höhe des Rechtecks weiterhin automatisch aktualisiert, so dass sie immer das Dreifache seiner Breite beträgt.

Debuggen des Überschreibens von Bindungen

Eine häufige Ursache von Fehlern in QML-Anwendungen ist das versehentliche Überschreiben von Bindungen mit statischen Werten aus JavaScript-Anweisungen. Um Entwicklern zu helfen, solche Probleme aufzuspüren, ist die QML-Engine in der Lage, Meldungen auszugeben, wenn eine Bindung aufgrund von imperativen Zuweisungen verloren geht.

Um solche Meldungen zu erzeugen, müssen Sie die Informationsausgabe für die Logging-Kategorie qt.qml.binding.removal aktivieren, zum Beispiel durch den Aufruf:

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

Weitere Informationen zur Aktivierung der Ausgabe von Logging-Kategorien finden Sie in der Dokumentation QLoggingCategory.

Beachten Sie, dass es unter bestimmten Umständen durchaus sinnvoll ist, Bindungen zu überschreiben. Jede von der QML-Engine erzeugte Meldung sollte als Diagnosehilfe betrachtet werden und nicht unbedingt als Beweis für ein Problem ohne weitere Untersuchung.

Verwendung von this mit Property Binding

Beim Erstellen einer Eigenschaftsbindung aus JavaScript kann das Schlüsselwort this verwendet werden, um auf das Objekt zu verweisen, das die Bindung erhält. Dies ist hilfreich, um Zweideutigkeiten bei Eigenschaftsnamen aufzulösen.

Zum Beispiel ist der Component.onCompleted Handler unten im Bereich von Item definiert. In diesem Bereich bezieht sich width auf die Breite von Item und nicht auf die Breite von Rectangle. Um die height des Rectangle an seine eigene width zu binden, muss der Bindungsausdruck explizit auf this.width (oder alternativ rect.width) verweisen:

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

Hinweis: Der Wert von this ist außerhalb von Property-Bindings nicht definiert. Siehe JavaScript-Umgebungseinschränkungen für Details.

Siehe auch Positionierung mit Ankern.

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