Wrong coordinates white getting real position of item relative to its parent

喜欢而已 提交于 2019-12-01 18:39:41

The documentation of Item proposes the mapToItem function:

Maps the point (x, y) or rect (x, y, width, height), which is in this item's coordinate system, to item's coordinate system, and returns an object with x and y (and optionally width and height) properties matching the mapped coordinate.

If item is a null value, this maps the point or rect to the coordinate system of the root QML view.

Since the coordinate must be in item' system, the correct way to call the function in your case would be:

<item_id>.mapToItem(<parent_id>, 0, 0)

where (0, 0) is the origin of <item_id> coordinates system.

Since in this case the parent is not an Item itself, we can exploit the null version of the method described by documentation and write:

<item_id>.mapToItem(null, 0, 0)

That's the theory. However, in this particular case (as noted by others), the layout management has not set the coordinate properties yet and thus the methods fail. That seems to be related to the non-consistent state in which items fall during initialisation. Indeed, if we use the function in the onDestruction handler, i.e. when we are sure that initialisation has finished, they give the expected results. See your modified code below:

import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Controls 1.3

Window  {
    visible: true
    width: 600
    height: 600

    Rectangle {
        id: rec1
        x: 200
        y: 200
        width: 200
        height: 200
        color: "green"
        opacity: 0.5
    }

    Rectangle {
        id: rec2
        width: 200
        height: 200
        anchors.centerIn: parent

        color: "blue"
        opacity: 0.5
    }

    Component.onCompleted: {
        console.info("NOPE! :(")
        var cords = rec1.mapToItem(null, 0, 0)
        console.info("rec1: " + cords.x + "  " + cords.y)
        cords = rec2.mapToItem(null, 0, 0)
        console.info("rec2: " + cords.x + "  " + cords.y)
    }

    Component.onDestruction: {
        console.info("YES! :)")
        var cords = rec1.mapToItem(null, 0, 0)
        console.info("rec1: " + cords.x + "  " + cords.y)
        cords = rec2.mapToItem(null, 0, 0)
        console.info("rec2: " + cords.x + "  " + cords.y)
        cords = rec2.mapToItem(null, 100, 100)      // (100, 100) of second rec is...
        console.info("rec2: " + cords.x + "  " + cords.y)   // correctly (300, 300)  !!
    }
}

Output:

qml: NOPE! :(
qml: rec1: 200  200
qml: rec2: -100  -100
qml: YES! :)
qml: rec1: 200  200
qml: rec2: 200  200
qml: rec2: 300  300

Both rectangles have same coordinates but on different time:

import QtQuick 2.4
import QtQuick.Window 2.2

Window {
    visible: true
    width: 600
    height: 600
    Rectangle {
        id: rec1
        x: 200
        y: 200
        width: 200
        height: 200
        color: "green"
        opacity: 0.5
        Component.onCompleted: console.log("rec1: " + rec1.x + "," + rec1.y);
    }

    Rectangle {
        id: rec2
        anchors.centerIn: parent
        width: 200
        height: 200
        color: "blue"
        opacity: 0.5
        Component.onCompleted: console.log("rec2: " + rec2.x + "," + rec2.y);
        onXChanged: console.log("rec2.x: " + rec2.x);
        onYChanged: console.log("rec2.y: " + rec2.y);
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!