ListElement
   
    一、描述
   
    列表元素,在
    
     
      ListModel
     
    
    中定义,并表示将使用
    
     
      ListView
     
    
    或
    
     
      Repeater
     
    
    项目显示的列表中的项目。
   
    列表元素包含
    
     
      角色定义
     
    
    的集合而不是属性。角色既定义了数据的访问方式,又包含了数据本身。
   
    用于角色的名称必须
    
     
      以小写字母开头
     
    
    ,并且应该对给定模型中的所有元素通用。值必须是简单的常量、字符串、布尔值、数字或枚举值。
   
允许将函数声明分配给角色。
    二、引用角色
   
代理使用角色名称从列表元素中获取数据。每个角色名称都可以在委托范围内访问,并引用当前元素中的相应角色。在角色名称使用不明确的情况下,可以通过模型属性访问它(例如,model.cost 而不是 cost)。
    三、使用示例
   
以下模型定义了一系列列表元素,每个元素都包含“name”和“cost”角色及其关联值。
ListModel 
{
    id: fruitModel
    ListElement 
    {
        name: "Apple"
        cost: 2.45
    }
    ListElement 
    {
        name: "Orange"
        cost: 3.25
    }
    ListElement 
    {
        name: "Banana"
        cost: 1.95
    }
}委托通过简单地引用名称和成本来获取每个元素的“name”和“cost”:
ListView 
{
    anchors.fill: parent
    model: fruitModel
    delegate: Row 
    {
        Text { text: "Fruit: " + name }
        Text { text: "Cost: $" + cost }
    }
}
    ListModel
   
    一、描述
   
    ListModel 是一个简单的
    
     
      ListElement
     
    
    定义容器,每个定义都包含数据角色。内容可以动态定义,也可以在 QML 中显式定义。
   
    二、使用示例
   
import QtQuick 2.0
Rectangle
{
    width: 200; height: 200
    ListModel //模型-提供数据
    {
        id: fruitModel
        ListElement 
        {
            name: "Apple"
            cost: 2.45
        }
        ListElement 
        {
            name: "Orange"
            cost: 3.25
        }
        ListElement 
        {
            name: "Banana"
            cost: 1.95
        }
    }
    Component //委托-提供一个展示数据的示例(如何展示一个模型中的数据)
    {
        id: fruitDelegate
        Row 
        {
            spacing: 10
            Text { text: name }
            Text { text: '$' + cost }
        }
    }
    ListView //视图-设置委托和模型,根据委托提供的展示方式展示模型提供的数据
    {
        anchors.fill: parent
        model: fruitModel
        delegate: fruitDelegate
    }
}
     
   
角色可以包含列表数据:
import QtQuick 2.12
import QtQuick.Window 2.0
Window
{
    id:root;
    visible: true;
    width: 1000;
    height: 500;
    title: "hello world"
    Rectangle
    {
        width: 200; height: 200
        ListModel {
            id: fruitModel
            ListElement
            {
                name: "苹果"
                cost: 2.45
                attributes:
                [
                    ListElement { description: "Core" },
                    ListElement { description: "Deciduous" }
                ]
            }
            ListElement
            {
                name: "橘子"
                cost: 3.25
                attributes:
                [
                    ListElement { description: "Citrus" }
                ]
            }
            ListElement
            {
                name: "香蕉"
                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: "属性:" }
                    Repeater
                    {
                        model: attributes
                        Text { text: description }
                    }
                }
            }
        }
        ListView
        {
            anchors.fill: parent
            model: fruitModel
            delegate: fruitDelegate
        }
    }
}
     
   
    三、修改列表模型
   
    可以使用
    
     clear
    
    ()、
    
     append
    
    ()、
    
     set
    
    ()、
    
     insert
    
    () 和
    
     setProperty
    
    () 方法创建和修改 ListModel 的内容。
   
例如:
        Component
        {
            id: fruitDelegate
            Item
            {
                width: 200; height: 50
                Text { text: name }
                Text { text: '$' + cost; anchors.right: parent.right }
                MouseArea
                {
                    anchors.fill: parent
                    onClicked: fruitModel.setProperty(index, "cost", cost * 2)
                }
            }
        }
     
   
在动态创建内容时,属性集一旦设置就无法更改。
    四、在
    
     WorkerScript
    
    中使用线程列表模型
   
    ListModel 可以与
    
     
      WorkerScript
     
    
    一起使用,从多个线程访问列表模型。列表操作可以移动到不同的线程以避免阻塞主 GUI 线程。
   
这是一个使用 WorkerScript 定期将当前时间附加到列表模型的示例:
import QtQuick 2.12
import QtQuick.Window 2.0
Window
{
    id:root;
    visible: true;
    width: 1000;
    height: 500;
    title: "hello world"
    Rectangle
    {
        width: 200; height: 200
        ListModel
        {
            id: listModel
        }
        Component
        {
            id: fruitDelegate
            Item
            {
                width: 200; height: 25
                Text { text: time }
            }
        }
        ListView
        {
            anchors.fill: parent
            model: listModel
            delegate: fruitDelegate
        }
        WorkerScript
        {
            id: worker
            source: "qrc:/dataloader.js"
        }
        Timer
        {
            id: timer
            interval: 1000; repeat: true
            running: true
            triggeredOnStart: true
            onTriggered:
            {
                var msg = {'action': 'appendCurrentTime', 'model': listModel};
                worker.sendMessage(msg);
            }
        }
    }
}dataloader.js
WorkerScript.onMessage = function(msg)
{
    if (msg.action === 'appendCurrentTime')
    {
        var data = {'time': new Date().toTimeString()};
        msg.model.append(data);
        msg.model.sync();
    }
}
     
   
    计时器通过调用
    
     
      WorkerScript
     
    
    ::
    
     sendMessage
    
    () 向工作脚本发送消息。收到此消息后,会在 dataloader.js 中调用
    
     
      WorkerScript
     
    
    .
    
     onMessage
    
    (),将当前时间附加到列表模型中。
   
    必须调用
    
     sync
    
    () 否则从该线程对列表所做的更改将不会反映在主线程的列表模型中。
   
    五、属性成员
   
    1、
    
     
      count
     
    
    : int
   
模型中数据条目的数量。
    2、
    
     
      dynamicRoles
     
    
    : bool
   
是否启用动态角色。默认被禁用。
默认情况下,角色的类型在第一次使用时固定。例如,创建一个名为“data”的角色并为其分配一个数字,则不能再为“data”角色分配字符串。但是,当启用 dynamicRoles 属性时,给定角色的类型不是固定的,元素之间可以不同。
dynamicRoles 属性必须在任何数据添加到 ListModel 之前设置,并且必须从主线程设置。
具有静态定义的数据(通过
ListElement
定义)的 ListModel 不能启用 dynamicRoles 属性。使用启用了动态角色的 ListModel 会产生显着的性能成本。成本因平台而异,但通常比使用静态角色类型慢 4-6 倍。
    六、成员函数
   
    1、
    
     append
    
    (jsobject dict)
   
将一个新项目添加到列表模型的末尾,其值在 dict 中。
    2、
    
     clear
    
    ()
   
从模型中删除所有内容。
    3、object
    
     get
    
    (int index)
   
返回列表模型中索引处的项目。这允许从 JavaScript 访问或修改项目数据。
Component.onCompleted: 
{
    fruitModel.append({"cost": 5.95, "name":"Jackfruit"});
    console.log(fruitModel.get(0).cost);
    fruitModel.get(0).cost = 10.95;
}此方法用于访问元素:
fruitModel.append(..., "attributes":
                        [{"name":"spikes","value":"7mm"},
                         {"name":"color","value":"green"}]);
fruitModel.get(0).attributes.get(1).value; // == "green"不保证返回的对象保持有效。不应该用于属性绑定。
    4、
    
     insert
    
    (int index, jsobject dict)
   
在位置 index 处向列表模型添加一个新项目,其值在 dict 中。
index 必须指向列表中的现有项目,或者列表末尾之后的一项(相当于
append
())。
fruitModel.insert(2, {"cost": 5.95, "name":"Pizza"})
    5、
    
     move
    
    (int from, int to, int n)
   
将 n 个项目从一个位置移动到另一个位置。from 和 to 范围必须存在。
例如,将前 3 个项目移动到列表的末尾:
fruitModel.move(0, fruitModel.count - 3, 3)
    6、
    
     remove
    
    (int index, int count = 1)
   
从模型中删除 index 处的计数项。
    7、
    
     set
    
    (int index, jsobject dict)
   
使用 dict 中的值更改列表模型中索引处的项目。
如果 index 等于
count
() ,则将新项目附加到列表中。否则,index 必须是列表中的元素。
fruitModel.set(3, {"cost": 5.95, "name":"Pizza"})
    8、
    
     setProperty
    
    (int index, string property, variant value)
   
将列表模型中 index 处项目的属性更改为 value。index 必须是列表中的元素。
fruitModel.setProperty(3, "cost", 5.95)
    9、
    
     sync
    
    ()
   
在从工作脚本修改列表模型后,将任何未保存的更改写入列表模型。
 
