Binding two words is a difficult question in QML, as it usually works as some kind of assignment.
So, if you bind a property with propertyname: valuetobeboundto
and later assign something to propertyname
again, that binding will be lost.
As a workaround, there are two ways: using Binding
objects or not using binding, but handle all the change-signals properties (which your model emits perfectly correctly) manually.
For the first you can find detailed instructions here. Here they use one Binding
-Object for each direction. Well, those Binding
will not be overridden by assigning a new Binding
.
Consider:
Row { spacing: 2 Rectangle { id: r0 width: 50 height: 30 } Rectangle { id: r1 width: 50 height: 30 color: b2.pressed ? 'red' : 'blue' } Button { id: b2 } Button { id: b3 onPressed: r1.color = 'black' onReleased: r1.color = 'green' } Binding { target: r0 property: 'color' value: b2.pressed ? 'red' : 'blue' } Binding { target: r0 property: 'color' value: (b3.pressed ? 'black' : 'green') } }
At the beginning, the value of r1
tied to state b2
, but once b3
been pressed once, r1
will not be updated by clicking on b2
anymore. For r0
update will be performed by two Binding
Objects, and therefore Binding
will not be lost. However, you can see how the binding works: when the Button
state ever changes, the Binding
will be updated. Thus, the press AND release of b2
will give signals that will be processed by the first Binding
, and the same for press And pass b3
.
Now go to two-way binding. It is important to avoid binding-cycles.
Row { Button { id: count0 property int count: 0 onClicked: count += 1 text: count } Button { id: count1 property int count: 0 onClicked: count += 1 text: count } Binding { target: count0 property: 'count' value: count1.count } Binding { target: count1 property: 'count' value: count0.count } }
So far this example is excellent. Changing count0.count
will cause a change to count1.count
. Now it is checked if count0.count
needs updating, but the value is already correct, so the recursion is completed, and no binding occurs.
Change second binding to
Binding { target: count1 property: 'count' value: count0.count + 1 }
dramatically changes the situation: now with each change in count0.count
you need to increase the value of count1.count
. The first Binding
then tries to set count0.count
to the same value as count1.count
, but it is simply not possible for both Binding
be completed and no changes are required after the other Binding
has worked. This will result in a binding cycle. Fortunately, in QML this is pretty well detected, so blocking can be avoided.
Now there is only one last concern: Consider this component definition:
// TestObj.qml Item { width: 150 height: 40 property alias color: rect.color Row { spacing: 10 Rectangle { id: rect width: 40 height: 40 radius: 20 color: butt.pressed ? 'green' : 'red' } Button { id: butt text: 'toggle' } } }
Here we have the internal binding color
property, using propertyname: valuetobeboundto
-Syntax. This means that the internal binding can be overwritten by any external destination of type color
. Replace this binding with a Binding
-Object, and you should be fine.
The same would be the other way around: color
externally bound to a certain value, and then you process the signal inside and assign a value to it, the external binding will be lost if a Binding
object is not created.
This is a general overview. There is more detailed information that can change the behavior of the binding. But I think I showed how you can create a two-way binding and mention some of the pitfalls that may arise.