Spec-Zone.ru › Qt 5.13

Тип QML ListModel

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

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

Свойства

  • count : int
  • dynamicRoles : bool

Методы

  • append(dict)
  • clear()
  • объект get(index)
  • insert(index, jsobject dict)
  • move(from, int to, int n)
  • remove(index, int count = 1)
  • set(index, jsobject dict)
  • setProperty(index, string property, variant value)
  • sync()

Подробное описание

Модель ListModel — это простой контейнер определений ListElement, каждый из которых содержит роли данных. Содержимое может быть определено динамически или явно в QML.

Количество элементов в модели можно получить из свойства count. Также предоставляется ряд знакомых методов для управления содержимым модели, включая append(), insert(), move(), remove() и set(). Эти методы принимают словари в качестве аргументов; они переводятся в объекты ListElement моделью.

Элементы можно обрабатывать через модель, используя метод setProperty(), который позволяет устанавливать и изменять роли указанного элемента.

Пример использования

Следующий пример демонстрирует ListModel, содержащий три элемента, с ролями «name» и «cost».

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 для доступа к модели списка из нескольких потоков. Это полезно, если операции модификации списка синхронны и занимают некоторое время: операции со списком можно перенести в другой поток, чтобы избежать блокировки основного потока графического интерфейса.

Вот пример, который использует 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(). При получении этого сообщения вызывается WorkerScript.onMessage() в dataloader.mjs, который добавляет текущее время в модель списка.

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

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

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

count : int

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

dynamicRoles : bool

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

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

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

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

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

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

append(dict)

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

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

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

clear()

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

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

объект get(index)

Возвращает элемент по индексу в модели списка. Это позволяет получать доступ к данным элемента или изменять их из JavaScript:

Component.onCompleted: {
    fruitModel.append({"cost": 5.95, "name":"Jackfruit"});
    console.log(fruitModel.get(0).cost);
    fruitModel.get(0).cost = 10.95;
}

Индекс должен находиться в списке.

Обратите внимание, что свойства возвращаемого объекта, которые сами являются объектами, также будут моделями, и для доступа к элементам используется метод get():

fruitModel.append(..., "attributes":
    [{"name":"spikes","value":"7mm"},
     {"name":"color","value":"green"}]);
fruitModel.get(0).attributes.get(1).value; // == "green"

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

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

insert(index, jsobject dict)

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

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

Индекс должен соответствовать существующему элементу в списке или одному элементу за концом списка (эквивалентно append).

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

move(from, int to, int n)

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

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

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

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

remove(index, int count = 1)

Удаляет содержимое по индексу из модели.

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

set(index, jsobject dict)

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

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

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

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

setProperty(index, string property, variant value)

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

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

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

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

sync()

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

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

Spec-Zone.ru

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