TableModel QML 类型

封装简单的表模型。 更多...

导入声明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 storing the copied model data in 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,因此该代理作为后备被声明在最后。

另见TableModelColumnTableViewQAbstractTableModel

属性文档

columnCount : int [只读]

这个只读属性包含模型中的列数。

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


rowCount : int [只读]

此只读属性包含模型中的行数。

当在模型中添加或删除行时,此值会发生变化。


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()、rowCountcolumnCount


方法文档

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


int index(int row, int column)

返回一个指向给定row和给定columnQModelIndex对象,可以将其传递给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))
        }
    }
}

另请参阅QModelIndex 和 QML 中相关类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(int fromRowIndexint toRowIndexint rows)

rows 从索引 fromRowIndex 移动到索引 toRowIndex

必须存在 from 和 to 范围;例如,将前 3 个元素移动到列表末尾

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

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


removeRow(int rowIndexint rows = 1)

从模型中删除 rowIndex 处的若干 rows

另请参阅 clear() 和 rowCount


bool setData(QModelIndex indexstring rolevariant value)

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

另请参阅 data() 和 index


setRow(int rowIndexobject row)

使用 row 更改模型中 rowIndex 处的行。

所有列/单元格必须出现在 row 中,并且顺序正确。

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

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

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


© 2024 Qt 公司有限公司。本文档中的文档贡献是各自所有者的版权。本文档受 GNU 自由文档许可证版本 1.3 的许可,该许可证由自由软件基金会发布。Qt 及相关标志是芬兰和/或世界其他地区的 Qt 公司有限公司的商标。所有其他商标都是其各自所有者的财产。