ListModel QML Type
定义自由格式列表数据源。更多
Import Statement: | 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 。
使用示例
下面的示例显示了一个包含三个元素的 ListModel,其角色分别为 "name "和 "cost"。
import QtQuick ListModel { id: fruitModel ListElement { name: "Apple" cost: 2.45 } ListElement { name: "Orange" cost: 3.25 } ListElement { name: "Banana" cost: 1.95 } }
每个元素中的角色(属性)必须以小写字母开头,并且应为模型中所有元素所共有。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() 向 Worker 脚本发送消息。收到消息后,dataloader.mjs
中的WorkerScript.onMessage()
将被调用,并将当前时间追加到列表模型中。
请注意外部线程对sync() 的调用。您必须调用sync() ,否则该线程对列表所做的更改将不会反映在主线程的列表模型中。
属性文档
count : int |
模型中数据项的数量。
dynamicRoles : bool |
默认情况下,角色类型在首次使用时是固定的。例如,如果创建了一个名为 "data "的角色并为其分配了一个数字,那么就不能再为 "data "角色分配字符串。但是,如果启用了 dynamicRoles 属性,给定角色的类型就不是固定的,可以在不同元素之间有所不同。
动态角色属性必须在任何数据添加到ListModel 之前设置,而且必须在主线程中设置。
静态定义数据(通过ListElement QML 语法)的ListModel 不能启用 dynamicRoles 属性。
使用启用了动态角色的ListModel 会产生很大的性能代价。这种代价因平台而异,但通常比使用静态角色类型慢 4-6 倍。
由于使用动态角色会产生性能代价,因此默认情况下禁用动态角色。
方法文档
append(jsobject dict) |
object 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"
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() |
从 Worker 脚本修改列表模型后,将任何未保存的更改写入列表模型。
© 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.