TableModel QML Type

封装一个简单的表格模型。更多

Import Statement: import Qt.labs.qmlmodels

属性

方法

  • appendRow(object row)
  • clear()
  • variant data(QModelIndex index, string role)
  • object getRow(int rowIndex)
  • QModelIndex index(int row, int column)
  • insertRow(int rowIndex, object row)
  • moveRow(int fromRowIndex, int toRowIndex, int rows)
  • removeRow(int rowIndex, int rows)
  • bool setData(QModelIndex index, string role, variant value)
  • setRow(int rowIndex, object row)

详细说明

TableModel 类型存储 JavaScript/JSON 对象,作为可与TableView 一起使用的表模型的数据。它旨在支持非常简单的模型,而无需在 C++ 中创建自定义的QAbstractTableModel 子类。

import QtQuick
import QtQuick.Window
import Qt.labs.qmlmodels

Window {
    width: 400
    height: 400
    visible: true

    TableView {
        anchors.fill: parent
        columnSpacing: 1
        rowSpacing: 1
        boundsBehavior: Flickable.StopAtBounds

        model: TableModel {
            TableModelColumn { display: "checked" }
            TableModelColumn { display: "amount" }
            TableModelColumn { display: "fruitType" }
            TableModelColumn { display: "fruitName" }
            TableModelColumn { display: "fruitPrice" }

            // Each row is one type of fruit that can be ordered
            rows: [
                {
                    // Each property is one cell/column.
                    checked: false,
                    amount: 1,
                    fruitType: "Apple",
                    fruitName: "Granny Smith",
                    fruitPrice: 1.50
                },
                {
                    checked: true,
                    amount: 4,
                    fruitType: "Orange",
                    fruitName: "Navel",
                    fruitPrice: 2.50
                },
                {
                    checked: false,
                    amount: 1,
                    fruitType: "Banana",
                    fruitName: "Cavendish",
                    fruitPrice: 3.50
                }
            ]
        }
        delegate:  TextInput {
            text: model.display
            padding: 12
            selectByMouse: true

            onAccepted: model.display = text

            Rectangle {
                anchors.fill: parent
                color: "#efefef"
                z: -1
            }
        }
    }
}

模型的初始行数据是通过rows 属性或调用appendRow() 设置的。模型中的每一列都通过声明TableModelColumn 实例来指定,每个实例的顺序决定了其列索引。一旦模型的Component::completed() 信号发出,列和角色就已确定,并在模型的生命周期内固定不变。

要访问特定行,可以使用getRow() 函数。也可以通过rows 属性直接访问模型的 JavaScript 数据,但这种方式无法修改模型数据。

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

也可以通过委托修改模型的数据,如上例所示:

        delegate:  TextInput {
            text: model.display
            padding: 12
            selectByMouse: true

            onAccepted: model.display = text

            Rectangle {
                anchors.fill: parent
                color: "#efefef"
                z: -1
            }
        }

如果修改角色的数据类型与设置的数据类型不匹配,则会通过QVariant 自动转换。

支持的行数据结构

TableModel 设计用于处理 JavaScript/JSON 数据,其中每一行都是一个简单的键对对象:

{
    // Each property is one cell/column.
    checked: false,
    amount: 1,
    fruitType: "Apple",
    fruitName: "Granny Smith",
    fruitPrice: 1.50
},
// ...

由于 Qt 中的模型操作是通过行和列索引完成的,而且对象键是无序的,因此必须通过TableModelColumn 指定每一列。这样就可以将 Qt 的内置角色映射到每一行对象中的任何属性。

它支持复杂的行结构,但功能有限。由于 TableModel 无法知道每一行的结构,因此无法对其进行操作。因此,TableModel 存储在rows 中的模型数据副本无法与 QML 中设置的源数据保持同步。由于这些原因,TableModel 需要依靠用户来处理简单的数据操作。

例如,假设您想为每列设置多个角色。一种方法是使用一个数据源,其中每一行是一个数组,每一个单元格是一个对象。要在 TableModel 中使用这种数据源,需要定义一个 getter 和 setter:

TableModel {
    TableModelColumn {
        display: function(modelIndex) { return rows[modelIndex.row][0].checked }
        setDisplay: function(modelIndex, cellData) {
                rows[modelIndex.row][0].checked = cellData
            }
    }
    // ...

    rows: [
        [
            { checked: false, checkable: true },
            { amount: 1 },
            { fruitType: "Apple" },
            { fruitName: "Granny Smith" },
            { fruitPrice: 1.50 }
        ]
        // ...
    ]
}

上面的行就是复杂行的一个示例。

注意: 使用复杂行时,不支持行操作函数,如appendRow(),removeRow() 等。

将 DelegateChooser 与 TableModel 结合使用

对于大多数实际用例,建议使用DelegateChooser 作为使用 TableModel 的TableView 的委托。这样就可以在相关委托中使用特定角色。例如,上面的代码段可以改写成这样:使用DelegateChooser

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

ApplicationWindow {
    width: 400
    height: 400
    visible: true

    TableView {
        anchors.fill: parent
        columnSpacing: 1
        rowSpacing: 1
        boundsBehavior: Flickable.StopAtBounds

        model: TableModel {
            TableModelColumn { display: "checked" }
            TableModelColumn { display: "amount" }
            TableModelColumn { display: "fruitType" }
            TableModelColumn { display: "fruitName" }
            TableModelColumn { display: "fruitPrice" }

            // Each row is one type of fruit that can be ordered
            rows: [
                {
                    // Each property is one cell/column.
                    checked: false,
                    amount: 1,
                    fruitType: "Apple",
                    fruitName: "Granny Smith",
                    fruitPrice: 1.50
                },
                {
                    checked: true,
                    amount: 4,
                    fruitType: "Orange",
                    fruitName: "Navel",
                    fruitPrice: 2.50
                },
                {
                    checked: false,
                    amount: 1,
                    fruitType: "Banana",
                    fruitName: "Cavendish",
                    fruitPrice: 3.50
                }
            ]
        }
        delegate: DelegateChooser {
            DelegateChoice {
                column: 0
                delegate: CheckBox {
                    checked: model.display
                    onToggled: model.display = checked
                }
            }
            DelegateChoice {
                column: 1
                delegate: SpinBox {
                    value: model.display
                    onValueModified: model.display = value
                }
            }
            DelegateChoice {
                delegate: TextField {
                    text: model.display
                    selectByMouse: true
                    implicitWidth: 140
                    onAccepted: model.display = text
                }
            }
        }
    }
}

首先声明最特殊的委托:索引01 中的列具有boolinteger 数据类型,因此它们分别使用CheckBoxSpinBox 。其余列可以简单地使用TextField ,因此该委托作为后备委托最后声明。

另请参阅 TableModelColumn,TableView, 和QAbstractTableModel

属性文档

columnCount : int [read-only]

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

在设置rows 属性或首次调用appendRow() 后,列数在模型的生命周期内是固定的。


rowCount : int [read-only]

此只读属性保存模型中的行数。

无论何时从模型中添加或删除行,该值都会改变。


rows : object

该属性以行数组的形式保存模型数据:

            rows: [
                {
                    // Each property is one cell/column.
                    checked: false,
                    amount: 1,
                    fruitType: "Apple",
                    fruitName: "Granny Smith",
                    fruitPrice: 1.50
                },
                {
                    checked: true,
                    amount: 4,
                    fruitType: "Orange",
                    fruitName: "Navel",
                    fruitPrice: 2.50
                },
                {
                    checked: false,
                    amount: 1,
                    fruitType: "Banana",
                    fruitName: "Cavendish",
                    fruitPrice: 3.50
                }
            ]

另请参阅 getRow(),setRow(),moveRow(),appendRow(),insertRow(),clear(),rowCount, 和columnCount


方法文档

appendRow(object row)

在模型末尾添加新行,其值(单元格)在row 中。

model.appendRow({
    checkable: true,
    amount: 1,
    fruitType: "Pear",
    fruitName: "Williams",
    fruitPrice: 1.50,
})

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


clear()

删除模型中的所有行。

另请参阅 removeRow()。


variant data(QModelIndex index, string role)

从给定index 的表格单元格返回属于给定role 的数据。

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


object getRow(int rowIndex)

返回模型中位于rowIndex 的行。

请注意,这等同于直接通过rows 属性访问行:

Component.onCompleted: {
    // These two lines are equivalent.
    console.log(model.getRow(0).display);
    console.log(model.rows[0].fruitName);
}

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

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


QModelIndex index(int row, int column)

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

import QtQml 2.14
import Qt.labs.qmlmodels 1.0

TableModel {
    id: model

    TableModelColumn { display: "fruitType" }
    TableModelColumn { display: "fruitPrice" }

    rows: [
        { fruitType: "Apple", fruitPrice: 1.50 },
        { fruitType: "Orange", fruitPrice: 2.50 }
    ]

    Component.onCompleted: {
        for (var r = 0; r < model.rowCount; ++r) {
            console.log("An " + model.data(model.index(r, 0)).display +
                        " costs " + model.data(model.index(r, 1)).display.toFixed(2))
        }
    }
}

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


insertRow(int rowIndex, object row)

rowIndex 位置向列表模型添加新行,其值(单元格)位于row

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

rowIndex 必须是列表中的现有项,或列表末尾的一项(等同于appendRow()).

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


moveRow(intfromRowIndexinttoRowIndexint行)

rowsfromRowIndex 的索引移至toRowIndex 的索引。

from 和 to 的范围必须存在;例如,将前 3 个项目移至列表末尾:

model.moveRow(0, model.rowCount - 3, 3)

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


removeRow(int rowIndex, int rows = 1)

从模型中移除rowIndex 中的rows

另请参阅 clear() 和rowCount


bool setData(QModelIndex index, string role, variant value)

在给定的index 的表格单元格中插入或更新由role 命名的数据字段,value 。如果成功则返回 true,否则返回 false。

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


setRow(int rowIndex, object row)

通过row 更改模型中rowIndex 处的行。

row 中必须包含所有列/单元格,且顺序正确。

model.setRow(0, {
    checkable: true,
    amount: 1,
    fruitType: "Pear",
    fruitName: "Williams",
    fruitPrice: 1.50,
})

如果rowIndex 等于rowCount() ,则会在模型中添加新行。否则,rowIndex 必须指向模型中的现有行。

另请参阅 appendRow(),insertRow() 和rowCount


© 2025 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.