Bindungen von Qt/QML-Eigenschaften werden nach einer JavaScript-Zuweisung unterbrochen

 C Programming >> C-Programmierung >  >> Tags >> Qt
Bindungen von Qt/QML-Eigenschaften werden nach einer JavaScript-Zuweisung unterbrochen

Eigenschaftsbindungen sind eines der mächtigsten Konzepte in Qt/QML. Mit Eigenschaftsbindungen können Sie Beziehungen zwischen verschiedenen Objekteigenschaften angeben. Wenn sich der Wert einer Eigenschaftsabhängigkeit ändert, wird die Eigenschaft automatisch gemäß der angegebenen Beziehung aktualisiert. Die QML-Engine überwacht die Eigenschaftsabhängigkeiten (d. h. die Variablen im Bindungsausdruck). Wenn eine Änderung erkannt wird, wertet die QML-Engine den Bindungsausdruck neu aus und wendet das neue Ergebnis auf die Eigenschaft an. Ein wenig bekannter Vorbehalt bei Eigenschaftsbindungen ist, dass sie nach einer statischen JavaScript-Zuweisung (property = value ). Dieser Beitrag zeigt Ihnen die verschiedenen Verhaltensweisen und wie Sie Qt.binding() verwenden Eigenschaftsbindungen über JavaScript zuweisen.

Beachten Sie, dass dieses Verhalten beabsichtigt und dokumentiert ist und in Situationen nützlich sein kann, in denen Sie eine Eigenschaftsbindung absichtlich aufheben möchten.

Dieser Beitrag soll Sie über die unterschiedlichen Verhaltensweisen informieren, da es verwirrend sein kann, wenn Sie nicht wissen, was passiert. Ein Kollege von mir arbeitete an einem Fehler, er war sich dieses Verhaltens nicht bewusst und es kostete ihn zwei Stunden, herauszufinden, dass es das zugrunde liegende Problem war. Könnte mir auch passieren, wenn Sie knietief in einer Debugging-Session stecken.

Demonstration

Das obige Bild zeigt das Problem.

Die obersten Button (id: boundButton ) text -Eigenschaft ist an TextField gebunden (id: bindableTextField ) text -Eigenschaft. Wenn Sie also den Text bearbeiten, wird der Text auf der Schaltfläche automatisch aktualisiert.

Die zweite Schaltfläche unterbricht die Bindung, indem sie eine JavaScript-Zuweisung in ihrem onClicked durchführt Funktion:

onClicked: boundButton.text = "Binding broken"

Wenn Sie auf die Schaltfläche geklickt haben und dann den Text in der TextField ändern , spiegelt der Text der Schaltfläche nicht mehr den Text wider, den Sie eingegeben haben.

Die letzte Schaltfläche stellt die Eigenschaftsbindung mit dem Qt.binding() wieder her Funktion:

onClicked: boundButton.text = Qt.binding(function () {
            return bindableTextField.text
        })
    }

Ein bisschen komplizierte Syntax, aber es erledigt die Arbeit.

Qt.binding()

Die Dokumentation besagt Folgendes:

Verwirrenderweise enthält diese Seite Beispiele für den zweiten Anwendungsfall, nicht für den ersten. Einfachere Beispiele finden Sie auf der anderen Dokumentseite, die unten transkribiert ist:

Das folgende Rectangle sorgt zunächst dafür, dass seine Höhe immer doppelt so hoch ist wie width . Wenn jedoch die Leertaste gedrückt wird, wird der aktuelle Wert von width*3 wird der Höhe als statischer Wert zugewiesen . Danach bleibt die Höhe auf diesem Wert fest, auch wenn sich die Breite ändert. Die Zuweisung des statischen Werts hebt die Bindung auf.

Rectangle {
    width: 100
    height: width * 2

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

Wenn Sie dem Rechteck eine feste Höhe geben und automatische Updates stoppen möchten, ist dies kein Problem. Wenn jedoch eine neue Beziehung zwischen Breite und Höhe hergestellt werden soll, muss der neue Bindungsausdruck in Qt.binding() eingeschlossen werden Funktion stattdessen:

Rectangle {
    width: 100
    height: width * 2

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

Jetzt, nachdem die Leertaste gedrückt wurde, wird die Höhe des Rechtecks ​​automatisch aktualisiert, um immer das Dreifache seiner Breite zu sein.

Der andere Anwendungsfall wird meiner Erfahrung nach nicht oft verwendet, oder zumindest nicht in den Projekten, an denen ich gearbeitet habe. Das dynamische Erstellen von QML-Objekten macht zunächst Spaß, aber Sie verlieren die Typsicherheit und es sind alles Zeichenfolgen, sodass das Ändern eines Namens zunächst gut funktioniert, bis Sie an anderer Stelle Laufzeitfehler erhalten. Vielleicht bin ich von der Sicherheit beim Kompilieren verwöhnt, aber so ein kleiner Tippfehler oder eine Umbenennung hat mich mehr erwischt, als ich zugeben möchte. Während es in C++ einfach nicht mehr kompiliert wird.