锚定中断 `mapFromItem`

Anchoring breaks `mapFromItem`

我有一个 Item,它应该总是相对于另一个 Item 绘制自己(没有锚定,因为它们可能不是兄弟姐妹或 parent->child . 为此,我使用 mapFromItem-方法继承每个 Item-后代。

import QtQuick 2.0

Rectangle {
    id: root
    property Item origin
    property point originPosition: parent.mapFromItem(origin, origin.width / 2, origin.height / 2)

    width: 10
    height: 10
    color: 'red'
    x: originPosition.x - 5
    y: originPosition.y - 5
}

这工作正常,只要我不使用锚点进行布局,但可能只有 xy,函数 parent.mapFromItem(...) 被调用, 在计算 origin 的位置之前,不会更新,因为参数本身没有改变。

我已经想到:好吧,那么"let them change!"并将调用修改为:

property point originPosition: parent.mapFromitem(origin.parent, origin.x, origin.y)

希望现在更新。似乎有效,直到引入了另一个也被锚定的层:

Item {
    id: root
    width: 800
    height: 800
    Item {
        width: 400
        height: 400
        anchors.centerIn: parent
        Item {
            id: myOrigin
            width: 100
            height: 100
            anchors.right: parent.right
            anchors.bottom: parent.bottom
        }
    }
}

现在我得到 myOrigin 在 parent 中的位置更新。但是它 parent 可能不在正确的位置,我不会得到这个更新,这又破坏了一切。

我怎样才能得到这个运行?

// 编辑:当然它也会中断,如果 parent 之一的位置在运行时发生变化,例如通过一个Animation,我认为应该用同样的方法解决。

我最后写了一个小的 JS 函数,它为我做映射。 为此,我向上爬对象树,直到根节点添加坐标,以找到 originroot 对象上的绝对位置。

然后我从 this 爬回 root 对象,减去坐标,使结果相对于 this

function map(itm, cord) {
    var c = itm[cord]
    for (; itm.parent !== null; itm = itm.parent) {
        console.log(itm, c)
        c += itm[cord]
    }
    itm = this.parent
    for (; itm.parent !== null; itm = itm.parent) {
        console.log(itm, c)
        c -= itm[cord]
    }
    return c
}

在我的示例中,它看起来像这样:

import QtQuick 2.7
Rectangle {
    width: 20
    height: 20
    color: 'green'

    x: map(origin, 'x')
    y: map(origin, 'y')

    property Item origin

    function map(itm, cord) {
        var c = itm[cord]
        for (; itm.parent !== null; itm = itm.parent) {
            console.log(itm, c)
            c += itm[cord]
        }
        itm = this.parent
        for (; itm.parent !== null; itm = itm.parent) {
            console.log(itm, c)
            c -= itm[cord]
        }
        return c
    }
}

这似乎很有效,至少对于浅层对象树是这样。