[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.


  • Moderators

    @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's scale property to trigger the binding for the x and y properties which works but these properties mapFromItem for both doesnot execute at same time and thus might be causing the problem.
    An alternative to is it to use onScaleChanged handler inside scaler item itself. So

    Rectangle {
        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 to target's coordinates we have added it's coordinates while the rest are redRects dimensions. Then we apply it to redRect.
    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.


  • Moderators

    @belab

    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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.