QML - 跟踪组件的全局位置

Kon*_*dej 12 qt qml qt-quick qtquick2

我想跟踪一个对象的全局位置(或相对于它的一个祖先)并将其绑定到其他项目的位置.

我正在考虑使用mapFromItem如下:

SomeObject {
  x: ancestor.mapFromItem(trackedObject, trackedObject.x, 0).x
  y: ancestor.mapFromItem(trackedObject, 0, trackedObject.y).y
}
Run Code Online (Sandbox Code Playgroud)

这种方法的问题是,它mapFromItem被评估一次,并且不会更新,因为其中一个参数得到更新.此外,映射有时返回由我无法在代码中跟踪的偏移量改变的新位置(但这不是手头的问题).

我的第二个想法是通过实现一个函数来计算全局位置,该函数将递归地求和偏移量,停止在提供的祖先(类似的东西calculateOffsetFrom(ancestor)).这仍然只是一个函数,就我而言,它不会被重新评估为祖先位置变化之一(除非,在该函数中,我将绑定调用它的onXChanged每一个信号的信号)沿途的祖先,这似乎是一个肮脏的解决方案).

所以最后我已经添加了我想要跟踪的对象的属性,然后我绑定到它们:

TrackedObject {
  property real offsetX: x + parent.x + parent.parent.x + parent.parent.parent.x ...
  property real offsetY: y + parent.y + parent.parent.y + parent.parent.parent.y ...
}

SomeObject {
  x: trackedObject.globalX
  y: trackedObject.globalY
}
Run Code Online (Sandbox Code Playgroud)

但是......好吧......这个根本不会扩展,而且会像它那样难看.

有谁知道如何以更清洁的方式解决这个问题?

编辑: 据我所知,在这种情况下我不能使用锚点.该SomeObject组件是一个自定义组件,从一个点到另一个点绘制贝塞尔曲线(它将连接两个TrackedObjects).为此,我需要坐标之间的差异.如果我是正确的锚,则不提供任何计算它们之间距离的方法.

The*_*roo 7

这是一个难点,但这是我在我的一个项目中使用的hack:使蓝色矩形在另一个父级而不是绿色矩形移动,与绿色矩形移动时保持对齐,当黄色矩形(绿色)时rect parent)移动:

import QtQuick 2.0;

Rectangle {
    id: window;
    width: 800;
    height: 480;

    property bool globalBit : true;

    function updatePos (item_orig, item_dest, bit) {
        var pos_abs = window.mapFromItem (item_orig.parent, item_orig.x, item_orig.y);
        return window.mapToItem (item_dest.parent, pos_abs.x, pos_abs.y);
    }

    Rectangle {
        id: rectYellow;
        width: 400;
        height: 300;
        x: 300;
        y: 200;
        color: "yellow";

        onXChanged: { globalBit = !globalBit; }
        onYChanged: { globalBit = !globalBit; }

        MouseArea {
            drag {
                target: rectYellow;
                minimumX: 0;
                minimumY: 0;
                maximumX: (rectYellow.parent.width - rectYellow.width);
                maximumY: (rectYellow.parent.height - rectYellow.height);
            }
            anchors.fill: parent;
        }
        Rectangle {
            id: rectGreen;
            x: 100;
            y: 100;
            width: 50;
            height: 50;
            color: "green";

            MouseArea {
                drag {
                    target: rectGreen;
                    minimumX: 0;
                    minimumY: 0;
                    maximumX: (rectGreen.parent.width - rectGreen.width);
                    maximumY: (rectGreen.parent.height - rectGreen.height);
                }
                anchors.fill: parent;
            }
        }
    }
    Rectangle {
        id: rectBlue;
        x: pos.x + 50;
        y: pos.y + 50;
        width: 50;
        height: 50;
        color: "blue";

        property var pos : updatePos (rectGreen, rectBlue, globalBit);
    }
}
Run Code Online (Sandbox Code Playgroud)

诀窍是使用mapfromItem和mapToItem将所有坐标带回第一个共同祖先,并强制重新计算函数,只需将一个全局布尔标志传递给计算函数,并将每个坐标转换为每个坐标地图上的一个可移动元素移动的时间......你不必把它放在每个地方,只是放在可以移动并且在祖先项目内的物品的父母身上.

所以它的工作原理,你的位置永远是正确的,而且它的可扩展性很强,而且不会添加太多代码.