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

Property binding problem



  • Hi, when applying property bindings in QML I have encountered one problem. When we have a parent component (Window) and a child (Rectangle), which has some properties bind to parent's (width, height, or anchors.fill: parent), when I change parents properties in JS code, and if I want to read the values of the child's properties (that are bound to parent's) in the same JS code, it shows the old values (not updated). It looks like that the change of parents properties hasn't been propagated to child's. Here is the example of this problem:

    Window {
        id:myWindow
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
        Rectangle{
            id:customRec
            width:parent.width
            height: parent.height
            color: "blue"
        }
        Button{
            id:myBtn
            onClicked: {
                myWindow.width = 800
                myWindow.height = 600
                console.log(customRec.width)
                console.log(customRec.height)
            }
        }
    }
    

    After clicking on the button, it shows:
    qml: 640
    qml: 480
    instead of 800 and 600, new values. Although the rectangle has been scaled well. After clicking again it will show updated values (800 and 600). Can someone please explain what is happening here and how can binding property change be propagated immediately to bound properties. I am using Qt 5.12.2 with msvc2017_64 compiler.



  • I think the problem may be that bindings are not executed directly, but queued. As a work around you can put console.log(), on onWidthChanged() and onHeightChanged() on your child Rectangle. This link may give you more information.



  • @mitaa257 said in Property binding problem:

    how can binding property change be propagated immediately to bound propertie

    Hello @mitaa257 and welcome to Qt Forum, as far as I known, the bindings in QML are not direct but queued. And I don't know if it is possible to define them as direct.
    So when changing width and height from myWindow the events are queued and will be executed when onClicked is finished.
    If you want to monitor customRec changes, you have to use onWidthChanged and onHeightChanged events (as @johngod suggest you)



  • @johngod and @KroMignon thank you very much for your answers it helped me to understand QML bindings better. I am new to QtQuick, thats why I thought that, when parent's width is changed a signal is emitted (like signal-slot mechanism in Qt) and that the code after emit will be executed only after the slot function is finished, instead it works like event and gets queued to Event loop.


  • Qt Champions 2018

    Not to be a troublemaker but what @johngod and @KroMignon said is incorrect.

    QML property bindings are in fact processed directly, not queued.
    The problem you are encountering here is that the Window doesn't notify its change directly but is waiting for the underlying window manager of the platform to notify it.

    If instead of putting your Rectangle directly in the Window but in an intermediate Item and change the width of it, the binding would be instantly executed because the Item emits its notify signal directly in the setter.

    That doesn't change the solution provided but it does change the reason why it happens.
    Note that doing logic in property change signal handlers is not the best practice, but for debugging its fine.


Log in to reply