QML类型:ListElement、ListModel

  • Post author:
  • Post category:其他


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

()

在从工作脚本修改列表模型后,将任何未保存的更改写入列表模型。



版权声明:本文为kenfan1647原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。