本页内容

TreeModel QML Type

封装了一个简单的树模型。更多...

Import Statement: import Qt.labs.qmlmodels
Since: Qt 6.10

属性

方法

  • void appendRow(var treeRow)
  • void appendRow(parent, var treeRow)
  • void clear()
  • variant data(index, string role)
  • var getRow(rowIndex)
  • QModelIndex index(list<int> treeIndex, int column)
  • QModelIndex index(int row, int column, var parent)
  • void insertRow(int rowIndex, object row) (since 6.12)
  • void insertRow(int rowIndex, QModelIndex parent, object row) (since 6.12)
  • bool moveRows(QModelIndex sourceParent, int sourceRow, int count, QModelIndex destinationParent, int destinationChild) (since 6.12)
  • void removeRow(rowIndex)
  • bool setData(index, variant value, string role)
  • void setRow(rowIndex, var treeRow)

详细说明

TreeModel 类型将 JavaScript/JSON 对象存储为树模型的数据,该模型可与TreeView 配合使用。其设计初衷是支持非常简单的模型,而无需在 C++ 中创建自定义的QAbstractItemModel 子类。

import QtQuick
import QtQuick.Controls
import Qt.labs.qmlmodels

ApplicationWindow {
    visible: true
    width: 500
    height: 500

    TreeView {
        id: treeView
        anchors.fill: parent

        selectionModel: ItemSelectionModel {}

        model: TreeModel {
            id: treeModel

            TableModelColumn {
                display: "checked"
            }
            TableModelColumn {
                display: "size"
            }
            TableModelColumn {
                display: "type"
            }
            TableModelColumn {
                display: "name"
            }
            TableModelColumn {
                display: "lastModified"
            }

            rows: [{
                    checked: false,
                    size: "—",
                    type: "folder",
                    name: "Documents",
                    lastModified: "2025-07-01",
                    rows: [{
                            checked: true,
                            size: "24 KB",
                            type: "file",
                            name: "Resume.pdf",
                            lastModified: "2025-06-20",
                        }, {
                            checked: false,
                            size: "2 MB",
                            type: "folder",
                            name: "Reports",
                            lastModified: "2025-06-10",
                            rows: [{
                                    checked: true,
                                    size: "850 KB",
                                    type: "file",
                                    name: "Q2_Report.docx",
                                    lastModified: "2025-06-15",
                                }, {
                                    checked: false,
                                    size: "1.2 MB",
                                    type: "file",
                                    name: "Q3_Plan.xlsx",
                                    lastModified: "2025-06-18",
                                }]
                        }]
                },
                {
                    checked: false,
                    size: "—",
                    type: "folder",
                    name: "Pictures",
                    lastModified: "2025-05-30",
                    rows: [{
                            checked: true,
                            size: "3.5 MB",
                            type: "file",
                            name: "Vacation.jpg",
                            lastModified: "2025-05-15",
                        }, {
                            checked: false,
                            size: "2.1 MB",
                            type: "file",
                            name: "Family.png",
                            lastModified: "2025-05-20",
                        }]
                }
            ]
        }

        delegate: TreeViewDelegate {}
    }
}

模型的初始数据可通过rows 属性或调用appendRow()来设置。模型中的每一列均通过声明一个TableModelColumn 实例来指定,其中每个实例的顺序决定其列索引。一旦模型的Component::completed()信号被触发,列和角色即被确立,并在模型的生命周期内保持不变。

支持的行数据结构

每行代表树中的一个节点。每个节点具有相同类型的列。TreeModel 专为处理 JavaScript/JSON 数据而设计,因此每行都是一个简单的键值对列表:

                {
                    checked: false,
                    size: "—",
                    type: "folder",
                    name: "Pictures",
                    lastModified: "2025-05-30",
                    rows: [{
                            checked: true,
                            size: "3.5 MB",
                            type: "file",
                            name: "Vacation.jpg",
                            lastModified: "2025-05-15",
                        }, {
                            checked: false,
                            size: "2.1 MB",
                            type: "file",
                            name: "Family.png",
                            lastModified: "2025-05-20",
                        }]
                }

一个节点可以拥有子节点,这些子节点将存储在与“rows”键关联的数组中。“rows”键专用于此目的:仅应将子节点列表与该键关联。

该模型通过 `QModelIndices` 进行操作。要访问特定行/节点,可使用 `getRow()` 函数。也可以通过 `rows ` 属性直接访问模型的 JavaScript 数据,但无法通过此方式修改模型数据。

要添加新行,请使用appendRow()。要修改现有行,请使用setRow()、removeRow() 和clear()。

将 TreeModel 与外部 JSON 数据源结合使用

虽然 TreeModel 的设计初衷是在 QML 文件中就地定义 JSON 数据,但只要其结构与 TreeModel 定义的结构匹配,您就可以将任何 JSON 对象与该模型配合使用。如果 JSON 对象的所有行都符合模型定义的列,则可以通过 rows 属性直接将其赋值。

JSON 对象的来源可以是一个文件。例如,如果模型定义为

    TreeModel {
        id: treeModel
        objectName: "testModel"

        TableModelColumn { display: "checked" }
        TableModelColumn { display: "size" }
        TableModelColumn { display: "type" }
        TableModelColumn { display: "name" }
        TableModelColumn { display: "lastModified" }
    }

而文件中存储的 JSON 对象如下所示

let folders = [
    {
        "checked": false,
        "size": "—",
        "type": "folder",
        "name": "Documents",
        "lastModified": "2025-07-01",
        "rows": [
            {
                "checked": true,
                "size": "24 KB",
                "type": "file",
                "name": "Resume.pdf",
                "lastModified": "2025-06-20"
            }
        ]
    },
    {
        "checked": false,
        "size": "—",
        "type": "folder",
        "name": "Pictures",
        "lastModified": "2025-05-30",
        "rows": [
            {
                "checked": true,
                "size": "3.5 MB",
                "type": "file",
                "name": "Vacation.jpg",
                "lastModified": "2025-05-15"
            }
        ]
    }
]

那么可以通过将该 JavaScript 文件导入为

模块

import "TreeData.js" as JsonData

,随后即可直接将其赋值

    Component.onCompleted: treeView.model.rows = JsonData.folders

警告:请确保 JSON 数据来自可信来源。由于模型会根据输入动态填充其行,格式错误或不可信的 JSON 可能会导致意外行为或性能问题。

请参阅TableModel ,该示例展示了将 JSON 对象解析为 JavaScript 数组并进行赋值的另一种方式。

另请参阅 TableModelColumn 和TreeView 。

属性文档

columnCount : int [read-only]

此只读属性存储模型中的列数。

在首次设置rows 属性或调用appendRow()之后,该列数在模型生命周期内保持不变。

rows : var

该属性以行数组的形式存储模型数据。

另请参阅 getRow(),setRow(),appendRow(),clear() 以及columnCount 。

方法文档

void appendRow(var treeRow)

将treeRow 追加到根节点。

另请参阅 setRow() 和removeRow()。

void appendRow(parent, var treeRow)

将一个新的 treeRow 追加到 `parent` 中,其值(单元格)来自 `treeRow`。

treeModel.appendRow(index, {
    checked: false,
    size: "-",
    type: "folder",
    name: "Orders",
    lastModified: "2025-07-02",
    rows: [
        {
            checked: true,
            size: "38 KB",
            type: "file",
            name: "monitors.xlsx",
            lastModified: "2025-07-02"
        },
        {
            checked: true,
            size: "54 KB",
            type: "file",
            name: "notebooks.xlsx",
            lastModified: "2025-07-02"
        }
    ]
});

parent 是一个由 `QModelIndex` 支持的匿名 QML 类型。如果 `parent ` 无效,则将 `treeRow ` 追加到根节点。

另请参阅 setRow() 和removeRow()。

void clear()

从模型中删除所有行。

另请参阅 removeRow()。

variant data(index, string role)

返回位于给定坐标index 处、属于给定坐标系role 的TreeModel 中的数据。

index 是一个由QModelIndex 支持的匿名QML类型。

另请参阅 index() 和setData()。

var getRow(rowIndex)

返回模型中指定索引处的 treeRow。rowIndex 是一个由QModelIndex 支持的匿名 QML 类型。

注意: 返回的对象不能用于修改模型的内容;请改用 setTreeRow()。

另请参阅 setRow()、appendRow() 和removeRow()。

QModelIndex index(list<int> treeIndex, int column)

返回一个引用给定treeIndex 和column 的对象,该对象可传递给data()函数以获取该单元格的数据,或传递给setData()函数以编辑该单元格的内容。

返回的对象是一个由QModelIndex 支持的匿名QML类型。

第一个参数treeIndex 表示从根节点到目标行的一系列行号路径,用于在树内进行导航。通过一个示例可以更好地说明这一点。

显示节点 A 至 F 及其索引路径的树形图
  • 树的根节点是特殊的,因为它可以通过一个无效的QModelIndex 进行引用。
  • 节点 A 是根节点的第一个子节点,其对应的treeIndex 为[0] 。
  • 节点 B 是节点 A 的第一个子节点。由于 A 的treeIndex 为[0] ,因此 B 的treeIndex 将是[0,0] 。
  • 节点 C 是节点 A 的第二个子节点,其treeIndex 为[0,1] 。
  • 节点 D 是节点 A 的第三个子节点,其treeIndex 为[0,2] 。
  • 节点 E 是根节点的第二个子节点,其treeIndex 为[1] 。
  • 节点 F 是根节点的第三个子节点,其treeIndex 为[2] 。

通过此重载,即使没有其父节点的QModelIndex ,也可以获取节点的QModelIndex 。

如果根据指定的列表未找到任何节点,则返回一个无效的模型索引。请注意,无效的模型索引是指向节点根节点的。

另请参阅 QModelIndex 以及 QML 中的相关类和data()。

QModelIndex index(int row, int column, var parent)

返回一个对象,该对象引用了给定parent 的row 和column 属性,该对象可传递给data()函数以获取该单元格的数据,或传递给setData()以编辑该单元格的内容。

返回的对象属于一种由QModelIndex 支持的匿名QML类型。

另请参阅 QModelIndex 以及 QML 中的相关类和data()。

[since 6.12] void insertRow(int rowIndex, object row)

在根项的rowIndex 位置插入一行,其值(单元格)来自row 。

该方法在 Qt 6.12 中引入。

另请参阅 appendRow()、setRow() 和removeRow()。

[since 6.12] void insertRow(int rowIndex, QModelIndex parent, object row)

在parent 中,于位置rowIndex 处插入一行,其值(单元格)来自row 。

model.insertRow(2, parentIndex, {
    checkable: true, checked: false,
    amount: 1,
    fruitType: "Pear",
    fruitName: "Williams",
    fruitPrice: 1.50,
})

该方法在 Qt 6.12 中引入。

另请参阅 appendRow()、setRow() 和removeRow()。

[since 6.12] bool moveRows(QModelIndex sourceParent, int sourceRow, int count, QModelIndex destinationParent, int destinationChild)

将从sourceRow 开始的count 行从sourceParent 移动到destinationParent ,并在destinationChild 之前插入。

destinationChild 指移动操作前该行在destinationParent 中的位置(移除前索引),这与QAbstractItemModel::beginMoveRows() 保持一致。

源范围和目标范围必须存在,且sourceParent 与destinationParent 不得重叠,以免父节点被移动到其子节点之下。

如果行已成功移动,则返回true ;否则返回false 。

该方法在 Qt 6.12 中引入。

另请参阅 appendRow()、insertRow() 和removeRow()。

void removeRow(rowIndex)

从模型中移除由rowIndex 引用的TreeRow。rowIndex 是一个由QModelIndex 支持的匿名QML类型。

treeModel.removeTreeRow(rowIndex)

另请参阅 clear()。

bool setData(index, variant value, string role)

使用value ,在指定index 位置的TreeRow中插入或更新名为role 的数据字段。若操作成功则返回true,否则返回false。

index 是一个由QModelIndex 支持的匿名QML类型。

另请参阅 data() 和index()。

void setRow(rowIndex, var treeRow)

将模型中位于rowIndex 的 TreeRow 替换为treeRow 。rowIndex 是一个由QModelIndex 支持的匿名 QML 类型。

包含子行的行将被拒绝。

treeRow 中必须包含所有列/单元格,且顺序必须正确。该行的子行不受影响。

treeModel.setRow(rowIndex, {
    checked: true,
    size: "-",
    type: "folder",
    name: "Subtitles",
    lastModified: "2025-07-07",
    iconColor: "blue"
});

另请参阅 appendRow()。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.