ListModel QML 类型
定义一个自由形式的列表数据源。 更多...
导入语句 | import QtQml.Models |
属性
- count : int
- dynamicRoles : bool
方法
- append(jsobject dict)
- clear()
- object get(int index)
- insert(int index, jsobject dict)
- move(int from, int to, int n)
- remove(int index, int count)
- set(int index, jsobject dict)
- setProperty(int index, string property, variant value)
- sync()
详细描述
ListModel 是一个简单的容器,包含 ListElement 定义,每个定义中包含数据角色。内容可以动态定义,或在 QML 中显式定义。
可以通过模型中的 count 属性获取模型中元素的数量。提供了一系列熟悉的方法来操作模型的内容,包括 append()、insert()、move()、remove() 和 set()。这些方法接受字典作为参数,由模型将它们转换为 ListElement 对象。
可以使用 setProperty() 方法通过模型操作元素,该方法允许设置和更改指定元素的角色。
ListModel 继承自 QAbstractListModel 并提供它的 Q_INVOKABLE 方法。例如,您可以使用 QAbstractItemModel::index 检索行和列的 QModelIndex。
示例用法
以下示例展示了一个包含三个元素且具有“name”和“cost”角色的 ListModel。
import QtQuick ListModel { id: fruitModel ListElement { name: "Apple" cost: 2.45 } ListElement { name: "Orange" cost: 3.25 } ListElement { name: "Banana" cost: 1.95 } }
每个元素中的角色(属性)必须以小写字母开始,并且在模型的所有元素中应该是通用的。《a href="qml-qtqml-models-listelement.html" translate="no">ListElement 文档提供了有关如何定义元素更详细的指南。
由于示例模型包含一个 id
属性,它可以被视图引用,例如本例中的 ListView
import QtQuick Rectangle { width: 200; height: 200 ListModel { id: fruitModel ... } Component { id: fruitDelegate Row { spacing: 10 Text { text: name } Text { text: '$' + cost } } } ListView { anchors.fill: parent model: fruitModel delegate: fruitDelegate } }
角色可以包含列表数据。以下示例中我们创建了一个水果属性的列表
ListModel { id: fruitModel ListElement { name: "Apple" cost: 2.45 attributes: [ ListElement { description: "Core" }, ListElement { description: "Deciduous" } ] } ListElement { name: "Orange" cost: 3.25 attributes: [ ListElement { description: "Citrus" } ] } ListElement { name: "Banana" cost: 1.95 attributes: [ ListElement { description: "Tropical" }, ListElement { description: "Seedless" } ] } }
委托显示所有水果属性
Component { id: fruitDelegate Item { width: 200; height: 50 Text { id: nameField; text: name } Text { text: '$' + cost; anchors.left: nameField.right } Row { anchors.top: nameField.bottom spacing: 5 Text { text: "Attributes:" } Repeater { model: attributes Text { text: description } } } } }
修改列表模型
可以使用以下方法创建和修改 clear()、append()、set()、insert() 和 setProperty() 的 ListModel
内容。例如
Component { id: fruitDelegate Item { width: 200; height: 50 Text { text: name } Text { text: '$' + cost; anchors.right: parent.right } // Double the price when clicked. MouseArea { anchors.fill: parent onClicked: fruitModel.setProperty(index, "cost", cost * 2) } } }
请注意,在动态创建内容时,一旦设置,可用的属性集不能更改。最初添加到模型中的所有属性都是模型中唯一允许的属性。
使用 WorkerScript 与线程化的列表模型
ListModel
可以与 WorkerScript 一起使用,从多个线程访问列表模型。如果列表修改是同步的且需要一些时间,这是很有用的:可以将列表操作移动到不同的线程,以避免阻塞主 GUI 线程。
以下是一个使用 WorkerScript 定期将当前时间追加到列表模型的示例
Timer { id: timer interval: 2000; repeat: true running: true triggeredOnStart: true onTriggered: { var msg = {'action': 'appendCurrentTime', 'model': listModel}; worker.sendMessage(msg); } }
包含的文件 dataloader.mjs
看起来是这样的
WorkerScript.onMessage = function(msg) { if (msg.action == 'appendCurrentTime') { var data = {'time': new Date().toTimeString()}; msg.model.append(data); msg.model.sync(); // updates the changes to the list } }
主示例中的计时器通过调用 WorkerScript::sendMessage() 向工作脚本发送消息。当接收到这条消息时,在 dataloader.mjs
中将调用 WorkerScript.onMessage()
,它将当前时间追加到列表模型。
请注意从外部线程调用 sync()。您必须调用 sync(),否则该线程所做的列表更改将不会反映在主线程的列表模型中。
属性文档
count : int |
模型中的数据条目数量。
dynamicRoles : bool |
默认情况下,角色类型在第一次使用时是固定的。例如,如果你创建了一个名为 "data" 的角色并将其分配给一个数字,你不能再将字符串分配给 "data" 角色。但是,当启用 dynamicRoles 属性时,给定角色的类型不是固定的,并且可以不同。
必须在向 ListModel 添加任何数据之前设置 dynamicRoles 属性,并且必须从主线程设置。
具有通过 ListElement QML 语法静态定义(定义)数据的 ListModel 不能启用 dynamicRoles 属性。
使用启用动态角色的 ListModel 的性能成本很高。成本因平台而异,但通常比使用静态角色类型慢 4-6 倍。
由于使用动态角色的性能成本很高,因此默认禁用。
方法文档
append(jsobject dict) |
对象 get(int index) |
返回列表模型中的 index 位置的项。这允许从 JavaScript 访问或修改项目数据
Component.onCompleted: { fruitModel.append({"cost": 5.95, "name":"Jackfruit"}); console.log(fruitModel.get(0).cost); fruitModel.get(0).cost = 10.95; }
index 必须是列表中的元素。
注意,返回对象的属性如果是自身也是对象,也将会是模型,此 get() 方法用于访问元素
fruitModel.append(..., "attributes": [{"name":"spikes","value":"7mm"}, {"name":"color","value":"green"}]); fruitModel.get(0).attributes.get(1).value; // == "green"
警告: 返回的对象不保证保持有效。不应在 属性绑定 中使用。
另请参阅 append。
insert(int index, jsobject dict) |
将 n 个项从位置 from 移动到 to 。
from 和 to 范围必须存在;例如,将前 3 个项移动到列表末尾
fruitModel.move(0, fruitModel.count - 3, 3)
另请参阅 append。
set(int index, jsobject dict) |
使用 dict 中的值更改列表模型中的 index 位置的项。未出现在 dict 中的属性保持不变。
fruitModel.set(3, {"cost": 5.95, "name":"Pizza"})
如果 index 等于 count(),则向列表中添加一项新项。否则,index 必须是列表中的元素。
另请参阅 append。
将列表模型中 index 位置的项的 property 更改为 value。
fruitModel.setProperty(3, "cost", 5.95)
index 必须是列表中的元素。
另请参阅 append。
sync() |
将修改后的列表模型中的任何未保存更改写入。
© 2024 Qt 公司有限公司。此处包含的文档贡献的版权为各自所有者所有。此处提供的文档是根据 Free Software Foundation 发布的 GNU 自由文档许可证版本 1.3 的条款许可的。Qt 和相应的标志是芬兰和/或其他国家的 Qt 公司的 商标。所有其他商标均为其各自所有者的财产。