Solved 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 changingwidth
andheight
frommyWindow
the events are queued and will be executed whenonClicked
is finished.
If you want to monitorcustomRec
changes, you have to useonWidthChanged
andonHeightChanged
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.
-
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.