Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Binding to properties of properties



  • The docs don't seem to spell out what happens if you say something like a: b.c where b is a reference to an object that has a c property. What I would hope for is:

    • a is bound to b, so that when I point b to a new object, a changes to the new b.c.
    • a is bound to b.c, so that when b.c changes, a changes.
    • When I point b to a new object, the binding from a to the old b.c is destroyed, and a binding to the new b.c is created, so that a follows changes to the new b.c.

    I would have thought this didn't work, since fixing up a whole bunch of bindings would seem too much to ask from the QML engine. But I wrote a simple test:

    import QtQuick 2.12
    import QtQuick.Window 2.12
    
    Window {
        visible: true
        width: 200
        height: 100
        title: "test"
    
        Rectangle {
            id: obj1
            objectName: "obj1"
            color: "red"
            x: 0
            width: 100
            y: 0
            height: 50
            property int count: 0
            Text {
                anchors.centerIn: parent
                text: parent.objectName + " = " + parent.count
                }
            MouseArea {
                anchors.fill: parent
                onClicked: ++parent.count
                onPressAndHold: obj.target = parent
                }
            }
    
        Rectangle {
            id: obj2
            objectName: "obj2"
            color: "yellow"
            x: 100
            width: 100
            y: 0
            height: 50
            property int count: 0
            Text {
                anchors.centerIn: parent
                text: parent.objectName + " = " + parent.count
                }
            MouseArea {
                anchors.fill: parent
                onClicked: ++parent.count
                onPressAndHold: obj.target = parent
                }
            }
    
        Rectangle {
            id: obj
            color: "cyan"
            x: 0
            width: 200
            y: 50
            height: 50
            property var target: obj1
            Text {
                anchors.centerIn: parent
                text: obj.target.objectName + " = " + obj.target.count
                }
            }
        }
    

    The red and yellow rectangles have counts that are incremented by clicking. The cyan rectangle shows the name and count of one of them. Long-pressing the red or yellow rectangle makes the cyan rectangle refer to it. When you do this, it appears that the binding to the old count is replaced with a binding to the new count.

    So it appears to work. Amazing.

    But the reason I'm asking about this is that I'm doing this sort of thing in an application, and it's not working. When I change what object a var property refers to, bindings to subsidiary properties of that object are not fixed up. Does anyone know why this would work in some circumstances and not in others? I don't see any mention of this sort of thing in the docs about bindings.


  • Moderators

    Please file a suggestion to fix the docs to Qt bugtracker.

    I suspect (just a guess) that if you defined your object as alias or QtObject it would have worked. It's very possible that QML engine assumes var to be "plain" JavaScript that does not need any further binding checks.


Log in to reply