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

如何在QML中正确遍历访问嵌套QStandardItemModel的子项

问题根因

你在深层DelegateModel中调用modelIndex(index)时,index是当前DelegateModel内部相对于父节点的行号,而modelIndex()方法默认基于模型的根节点创建索引,导致最终指向了错误的模型节点,所以第三层数据异常。另外你所有Delegate的Item都设置了Layout.fillHeight: true,会导致不同层级的控件相互拉伸重叠,也是显示异常的诱因之一。

修复方案

方案1:直接适配现有三层结构

你可以在每一层提前存储当前节点的完整QModelIndex,下层直接引用该索引作为rootIndex,修改后的代码如下:

ColumnLayout {
    anchors.fill: parent

    Repeater {
        model: backend.model

        Item {
            Layout.fillWidth: true
            Layout.preferredHeight: childrenRect.height
            // 存储顶层节点的完整索引
            property var topItemIndex: modelIndex(index)

            ColumnLayout {
                anchors.fill: parent

                Text {
                    color: "blue"
                    text: model.display
                }

                Repeater {
                    model: DelegateModel {
                        model: backend.model
                        rootIndex: parent.topItemIndex
                    }

                    Item {
                        Layout.fillWidth: true
                        Layout.preferredHeight: childrenRect.height
                        // 存储一级子节点的完整索引
                        property var subItemIndex: parent.topItemIndex.child(index, 0)

                        ColumnLayout {
                            anchors.fill: parent

                            Text {
                                color: "green"
                                text: model.display
                            }

                            Repeater {
                                model: DelegateModel {
                                    model: backend.model
                                    rootIndex: parent.subItemIndex
                                }

                                Text {
                                    color: "red"
                                    text: model.display
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

方案2:通用递归组件(适配任意层级嵌套)

如果你的树形结构层级不固定,可以使用递归组件自动遍历所有层级,不用写死嵌套层数:

  1. 首先新建递归组件TreeItem.qml:
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQml.Models 2.15

ColumnLayout {
    // 外部传入的全局模型
    property var rootModel
    // 当前层级的父节点索引,顶层传入无效索引即可
    property var parentIndex
    // 当前层级,可用于区分颜色、设置缩进
    property int level: 0

    Repeater {
        model: DelegateModel {
            model: rootModel
            rootIndex: parentIndex
        }

        ColumnLayout {
            // 按层级设置缩进,更符合树形结构展示习惯
            Layout.leftMargin: level * 20
            Layout.fillWidth: true
            Layout.preferredHeight: childrenRect.height

            Text {
                // 按层级匹配颜色,层级超过3时默认黑色
                color: ["blue", "green", "red"][level] || "black"
                text: model.display
            }

            // 递归加载子节点,只有存在子节点时才渲染
            TreeItem {
                rootModel: parent.rootModel
                parentIndex: parent.parentIndex.child(index, 0)
                level: parent.level + 1
                visible: rootModel.hasChildren(parent.parentIndex.child(index, 0))
            }
        }
    }
}
  1. 在主页面直接调用组件即可:
ColumnLayout {
    anchors.fill: parent
    TreeItem {
        rootModel: backend.model
        // 传入模型根节点的无效父索引
        parentIndex: backend.model.index(-1, 0)
        level: 0
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 08:57:03