[SOLVED]mapFromItem in QML Bindings
-
Hi,
I would like to have a red rectangle following another rectangle wich moves within an animated scaling parent. With the following example I'm getting strange effects: the red rectangle appears flickering at two positions. One of those positions is completely wrong, the other position deviates from its target position direct proportional to the current scaling. Here's the code:import QtQuick 2.4 import QtQuick.Controls 1.3 ApplicationWindow { title: qsTr("Hello World") width: 640; height: 480 visible: true Rectangle { anchors.fill: parent Rectangle { color: "#770000AA" id: scaler x: 160; y: 0 width: 320; height: 240 transformOrigin: Item.Top SequentialAnimation on scale { loops: Animation.Infinite NumberAnimation { to: 1.2; duration: 1000 } NumberAnimation { to: 1.0; duration: 1000 } } Rectangle { id: target width: 20; height: 20 x: 50; y: 200 } } Rectangle { color: "#FF0000" width: 10; height: 10 x: { scaler.scale // dummy to force evaluation return mapFromItem(target, 10, 10).x } y: { scaler.scale // dummy to force evaluation return mapFromItem(target, 10, 10).y } } } }
Any ideas on what's going wrong here are welcome.
-
Any expert around here? Does no one have an idea or seen a similar issue? I found some threads on stackoverflow but they were not very helpful. I would expect this to work in a binding even without the force dummy evaluation. If the scripts are evaluated, what are the constraints, how could I find it out without debugging it (absolutely no clue how to do that with script bindings). If it would be an issue with the evaluation order, the red rectangle would have a delay of one frame which is not the case.
-
Any expert around here? Does no one have an idea or seen a similar issue? I found some threads on stackoverflow but they were not very helpful. I would expect this to work in a binding even without the force dummy evaluation. If the scripts are evaluated, what are the constraints, how could I find it out without debugging it (absolutely no clue how to do that with script bindings). If it would be an issue with the evaluation order, the red rectangle would have a delay of one frame which is not the case.
@belab the problem that I see here for flickering is that the red rectangle is being painted at two locations alternately. You have binded
scaler
'sscale
property to trigger the binding for thex
andy
properties which works but these propertiesmapFromItem
for both doesnot execute at same time and thus might be causing the problem.
An alternative to is it to useonScaleChanged
handler insidescaler
item itself. SoRectangle { color: "#770000AA" id: scaler ... ... onScaleChanged: { var p = mapToItem(parent,50,200,10,10) redRect.scale = scale redRect.x = p.x redRect.y = p.y } }
This will map the coordinates to the parent Rectangle of
scaler
and since we want it to adjust totarget
's coordinates we have added it's coordinates while the rest areredRect
s dimensions. Then we apply it toredRect
.
Hope this is what you were expecting... -
@p3c0 Your proposal works fine. I think this way is better because it doesn't make implicit assumptions about how bindings are implemented. Regarding the explanation that both bindings are not executed at the same time I tried to remove the binding for "y". The red rectangle is still flickering. It seems like the targets position is alternating evaluated by covering its parent
scaler
and then covering its global root.
Thanks so far, I guess a lot of people will encounter this issue as well. -
@p3c0 Your proposal works fine. I think this way is better because it doesn't make implicit assumptions about how bindings are implemented. Regarding the explanation that both bindings are not executed at the same time I tried to remove the binding for "y". The red rectangle is still flickering. It seems like the targets position is alternating evaluated by covering its parent
scaler
and then covering its global root.
Thanks so far, I guess a lot of people will encounter this issue as well.Regarding the explanation that both bindings are not executed at the same time I tried to remove the binding for "y". The red rectangle is still flickering. It seems like the targets position is alternating evaluated by covering its parent scaler and then covering its global root.
Yes it seems. Thats why I said might in hurry :)
Thanks so far, I guess a lot of people will encounter this issue as well.
You're Welcome :). In that case you should mark the post as [Solved] so that other will be able to find it out.