Spec-Zone.ru › Qt 5.11

Тип QML ListModel

Определяет источник данных списка произвольной формы. Подробнее...

Оператор импорта: import QtQml.Models 2.11
  • Список всех членов, включая унаследованные члены

Свойства

  • 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 = 1)
  • 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, содержащий три элемента с ролями «имя» и «стоимость».

import QtQuick 2.0

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 2.0

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 }
            }
        }
    }
}

Изменение моделей списков

Содержимое ListModel можно создавать и изменять, используя методы clear(), append(), set(), insert() и setProperty(). Например:

    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.js, выглядит следующим образом:

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
    }
}

Таймер в основном примере отправляет сообщения в скрипт worker, вызывая WorkerScript::sendMessage(). При получении этого сообщения вызывается WorkerScript.onMessage() в dataloader.js, который добавляет текущее время в модель списка.

Обратите внимание на вызов sync() из внешнего потока. Вы должны вызвать sync(), иначе изменения, внесённые в список из этого потока, не будут отражены в модели списка в основном потоке.

См. также Модели данных, Примеры Qt Quick — Потоки и Qt QML.

Документация по свойствам

count : int

Количество записей данных в модели.

dynamicRoles : bool

По умолчанию тип роли фиксируется при первом использовании роли. Например, если вы создаёте роль «данные» и присваиваете ей число, вы больше не сможете присвоить строку роли «данные». Однако, когда свойство dynamicRoles включено, тип данной роли не фиксируется и может отличаться между элементами.

Свойство dynamicRoles должно быть установлено до добавления данных в ListModel и должно быть установлено из основного потока.

ListModel, у которого данные определены статически (через синтаксис QML ListElement), не может иметь включённое свойство dynamicRoles.

Использование ListModel с динамическими ролями имеет существенную затрату производительности. Затраты варьируются от платформы к платформе, но обычно находятся где-то между 4-6 раз медленнее, чем использование статических типов ролей.

Из-за затрат производительности при использовании динамических ролей они отключены по умолчанию.

Документация по методам

append(jsobject dict)

Добавляет новый элемент в конец модели списка со значениями в dict.

fruitModel.append({"cost": 5.95, "name":"Pizza"})

См. также set() и remove().

clear()

Удаляет всё содержимое из модели.

См. также append() и remove().

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"

Предупреждение: Возвращаемый объект не гарантируется как неизменяемый. Он не должен использоваться в связях свойств.

См. также append().

insert(int index, jsobject dict)

Добавляет новый элемент в модель списка в позиции index со значениями в dict.

fruitModel.insert(2, {"cost": 5.95, "name":"Pizza"})

index должен соответствовать существующему элементу списка или быть за его пределами (равнозначно append).

См. также set() и append().

move(int from, int to, int n)

Перемещает n элементов из одной позиции from в другую to.

Диапазоны from и to должны существовать; например, для перемещения первых 3 элементов в конец списка:

fruitModel.move(0, fruitModel.count - 3, 3)

См. также append().

remove(int index, int count = 1)

Удаляет содержимое в позиции index из модели.

См. также clear().

set(int index, jsobject dict)

Изменяет элемент в позиции index в модели списка со значениями в dict. Свойства, отсутствующие в dict, остаются без изменений.

fruitModel.set(3, {"cost": 5.95, "name":"Pizza"})

Если index равен count(), то новый элемент добавляется в список. В противном случае index должен быть элементом в списке.

См. также append().

setProperty(int index, string property, variant value)

Изменяет свойство property элемента в позиции index в модели списка на значение value.

fruitModel.setProperty(3, "cost", 5.95)

index должен быть элементом в списке.

См. также append().

sync()

Записывает все несохраненные изменения в модель списка после ее изменения из скрипта рабочего потока.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/archives/qt-5.11/qml-qtqml-models-listmodel.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API