Тип QML ListModel
Определяет источник данных списка произвольной формы Подробнее...
| Заявление об импорте: | import QtQml.Models 2.2 |
Свойства
- 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, содержащий три элемента с ролями "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 для доступа к модели списка из нескольких потоков. Это полезно, если операции изменения списка выполняются синхронно и занимают некоторое время: операции со списком могут быть перемещены в другой поток, чтобы избежать блокировки основного потока 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
}
} Таймер в основном примере отправляет сообщения в скрипт рабочего потока, вызывая WorkerScript::sendMessage(). При получении этого сообщения вызывается WorkerScript.onMessage() в dataloader.js, которое добавляет текущее время в модель списка.
Обратите внимание на вызов sync() из внешнего потока. Вы должны вызвать sync(), иначе изменения, внесённые в список из этого потока, не будут отражены в модели списка в главном потоке.
См. также Модели данных, Примеры Qt Quick - Потоки и Qt QML.
Документация по свойствам
count : int
Количество записей данных в модели.
dynamicRoles : bool
По умолчанию тип роли фиксируется в первый раз при использовании роли. Например, если вы создаёте роль с именем "data" и присваиваете ей число, вы больше не можете присвоить строку роли "data". Однако, когда свойство dynamicRoles включено, тип заданной роли не фиксируется и может отличаться между элементами.
Свойство dynamicRoles должно быть установлено до добавления любых данных в ListModel и должно устанавливаться из главного потока.
ListModel, у которого данные определены статически (через синтаксис QML ListElement), не может иметь включённое свойство dynamicRoles.
Использование ListModel с включёнными динамическими ролями имеет существенные затраты на производительность. Затраты различаются в зависимости от платформы, но обычно находятся в диапазоне от 4 до 6 раз медленнее, чем использование статических типов ролей.
Из-за затрат на производительность использование динамических ролей отключено по умолчанию.
Документация по методам
append(jsobject dict)
Добавляет новый элемент в конец модели списка со значениями из dict.
fruitModel.append({"cost": 5.95, "name":"Pizza"}) 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).
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.6/qml-qtqml-models-listmodel.html