You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取QML GridView中每个委托项的屏幕位置?

解决QML GridLayout中项的独立屏幕位置获取问题

问题根源很明确:onItemAdded触发时,Repeater刚创建完组件,但GridLayout还没完成布局计算,所有项的x、y还停留在初始值0,所以调用mapToGlobal得到的自然是同一个位置。

下面是几个可行的解决方法:

方法1:用Layout.onLayouted监听布局完成

GridLayout的子项可以通过Layout.onLayouted信号感知布局完成,此时项的位置已经被正确分配:

GridLayout {
    columns: 2

    Repeater {
        model: inputs

        Text { 
            text: title 
            Layout.fillWidth: true // 根据需求设置布局属性,可选

            Layout.onLayouted: {
                const pos = mapToGlobal(x, y);
                console.log("Position:", pos, "X: ", x, "Y: ", y);
            }
        }
    }
}

方法2:延迟获取位置(兼容旧版本场景)

如果没法用Layout.onLayouted,可以用短延迟的Timer等布局完成后再获取:

GridLayout {
    columns: 2

    Repeater {
        model: inputs

        Text { text: title }

        onItemAdded: (idx, item) => {
            Timer {
                interval: 10 // 足够布局完成的短延迟,可按需调整
                running: true
                repeat: false
                onTriggered: {
                    const pos = item.mapToGlobal(item.x, item.y);
                    console.log("Position:", pos, "X: ", item.x, "Y: ", item.y);
                }
            }
        }
    }
}

补充:如果实际用的是GridView(问题开头提到的)

如果你的真实场景是GridView而非GridLayout,可以利用它的onPositioningComplete信号,或者在代理里监听位置变化:

GridView {
    id: gridView
    model: inputs
    delegate: Text { text: title }

    onPositioningComplete: {
        for (let i = 0; i < count; i++) {
            const item = gridView.itemAt(i);
            if (item) {
                const pos = item.mapToGlobal(item.x, item.y);
                console.log("Item", i, "Position:", pos);
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者rprospero

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 20:27:16