QML types: Repeater, ListElement, ListModel

Repeater

1. Description

The Repeater type is used to create a large number of similar items. is a view element. Like other view types, a Repeater has a model and a delegate.

Repeater items are often wrapped in a locator type, such as Row or Column, to visually locate multiple delegate items created by a Repeater.

The following Repeater creates three instances of Rectangle items in a row:

import QtQuick 2.0

Row
{
Repeater
{
model: 3
Rectangle
{
width: 100; height: 40
border. width: 1
color: "yellow"
}
}
}

The Repeater’s model can be any supported data model. Also, like other view delegates, a Repeater delegate has access to its index in the Repeater, as well as model data associated with the delegate.

Items instantiated by a Repeater are inserted sequentially, as children of the Repeater’s parent. A Repeater item owns all items it instantiates. Removing or dynamically destroying items created by a Repeater can result in unpredictable behavior.

A Repeater type creates all of its delegate items when the Repeater is first created. This can be inefficient if there are a large number of delegated items and not all of them need to be visible at the same time. In this case, consider using another view type such as ListView (which only creates delegate items when scrolled into view) or using dynamic object creation to create items when needed.

Also note that Repeater is based on Item and can only repeat Item -derived objects. For example, it cannot be used to duplicate QtObjects:

// Bad code:

Item
{
Repeater
{
model: 10
QtObject {}
}
}

2. Attribute members

1. count: int

This property holds the number of items in the model.

2. delegate: Component [default type (delegate omitted)]

The delegate provides a template that defines each item instantiated by the Repeater.

Delegates are exposed to a read-only index property that indicates the index of the delegate within the Repeater.

For example, the following Text delegate displays the index of each repetition:

If the model is a list of strings or a list of objects, the delegate is also exposed to a read-only modelData property containing string or object data. For example:

3. model: any

The model that provides data to the Repeater.

This property can be set to any supported data model:

A number representing the number of delegates to be created by the relayer

Models (such as ListModel items or QAbstractItemModel subclasses)

a list of strings

object list

The type of model affects the properties exposed to the delegate.

3. Signal member

1. itemAdded(int index, Item item)

This signal is emitted when an item is added to the Repeater.

The index parameter holds the index of the inserted item in the Repeater, and the item parameter holds the added item.

2. itemRemoved(int index, Item item)

This signal is emitted when an item is removed from the repeater. The index parameter holds the index of the item removed from the forwarder, while the item parameter holds the item removed.

Do not keep a reference to the item if it was created by this repeater, because in these cases it will be deleted shortly after the signal is processed.

4. Member functions

1. Item itemAt(index)

Returns the item already created at the given index, or null if no item exists at the index.

ListElement

1. Description

A list element, defined in a ListModel, and represents an item in a list that will be displayed using a ListView or Repeater item.

List elements contain collections of role definitions rather than attributes. Roles define both how data is accessed and the data itself.

Names used for roles must start with a lowercase letter and should be common to all elements in a given model. Values must be simple constants, strings, booleans, numbers, or enumerations.

Allows assignment of function declarations to roles.

Second, reference roles

The agent gets data from the list element using the role name. Each role name is accessible within the delegate scope and refers to the corresponding role in the current element. In cases where the use of a role name is ambiguous, it can be accessed through a model attribute (e.g. model.cost instead of cost).

3. Example

The following model defines a series of list elements, each containing the “name” and “cost” roles and their associated values.

ListModel
{
id: fruitModel

ListElement
{
name: "Apple"
cost: 2.45
}
ListElement
{
name: "Orange"
cost: 3.25
}
ListElement
{
name: "Banana"
cost: 1.95
}
}

The delegate gets the “name” and “cost” of each element by simply referencing the name and cost:

ListView
{
anchors. fill: parent
model: fruitModel
delegate: Row
{
Text { text: "Fruit: " + name }
Text { text: "Cost: $" + cost }
}
}

The benefits of this article,Fees to receive Qt development learning materials package, technical video, including (C++ language foundation, introduction to Qt programming, QT signal and slot mechanism, QT interface development – Image drawing, QT network, QT database programming, QT project combat, QT embedded development, Quick module, etc.) ↓↓↓↓↓↓See below↓↓Click at the bottom of the article to receive the fee↓↓

ListModel

1. Description

ListModel is a simple container of ListElement definitions, each definition containing data roles. Content can be defined dynamically or explicitly in QML.

2. Example

import QtQuick 2.0

Rectangle
{
width: 200; height: 200

ListModel //model - provide data
{
id: fruitModel
ListElement
{
name: "Apple"
cost: 2.45
}
ListElement
{
name: "Orange"
cost: 3.25
}
ListElement
{
name: "Banana"
cost: 1.95
}
}

Component //delegate-provide an example of displaying data (how to display data in a model)
{
id: fruitDelegate
Row
{
spacing: 10
Text { text: name }
Text { text: '$' + cost }
}
}

ListView //View – set the delegate and model, and display the data provided by the model according to the display method provided by the delegate

{
anchors. fill: parent
model: fruitModel
delegate: fruitDelegate
}
}

Roles can contain list data:

import QtQuick 2.12
import QtQuick.Window 2.0

windows
{
id: root;
visible: true;
width: 1000;
height: 500;
title: "hello world"

Rectangle
{
width: 200; height: 200

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: "Property:" }
Repeater
{
model: attributes
Text { text: description }
}
}
}
}

ListView
{
anchors. fill: parent
model: fruitModel
delegate: fruitDelegate
}
}
}

3. Modify the list model

The contents of a ListModel can be created and modified using the clear(), append(), set(), insert(), and setProperty() methods.

For example:

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

When creating content dynamically, the property set cannot be changed once set.

Fourth, use the thread list model in WorkerScript

ListModel can be used with WorkerScript to access the list model from multiple threads. List operations can be moved to a different thread to avoid blocking the main GUI thread.

Here’s an example that uses WorkerScript to periodically append the current time to a list model:

import QtQuick 2.12
import QtQuick.Window 2.0

windows
{
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();
}
}

The timer sends a message to the worker script by calling WorkerScript::sendMessage(). When this message is received, WorkerScript.onMessage() is called in dataloader.js to append the current time to the list model.

You must call sync() otherwise changes to the list from this thread will not be reflected in the main thread’s list model.

5. Attribute members

1. count: int

The number of data entries in the model.

2. dynamicRoles: bool

Whether to enable dynamic roles. Disabled by default.

By default, a character’s type is fixed on first use. For example, if you create a role named “data” and assign it a number, you can no longer assign a string to the “data” role. However, when the dynamicRoles attribute is enabled, the type of a given role is not fixed and can vary between elements.

The dynamicRoles property must be set before any data is added to the ListModel, and must be set from the main thread.

A ListModel with statically defined data (defined via ListElement) cannot have the dynamicRoles property enabled.

There is a significant performance cost to using a ListModel with dynamic roles enabled. Cost varies by platform, but is typically 4-6x slower than using static character types.

6. Member functions

1. append(jsobject dict)

Add a new item to the end of the list model with the value in the dict.

2. clear()

Remove everything from the model.

3. object get(int index)

Returns the item at index in the list model. This allows accessing or modifying project data from JavaScript.

Component.onCompleted:
{
fruitModel.append({"cost": 5.95, "name":"Jackfruit"});
console.log(fruitModel.get(0).cost);
fruitModel.get(0).cost = 10.95;
}
This method is used to access elements:
fruitModel.append(..., "attributes":
[{"name":"spikes","value":"7mm"},
{"name":"color","value":"green"}]);

fruitModel.get(0).attributes.get(1).value; // == "green"

The returned object is not guaranteed to remain valid. Should not be used for property binding.

4. insert(int index, jsobject dict)

Adds a new item to the list model at position index with value in dict.

index must point to an existing item in the list, or an item after the end of the list (equivalent to append()).

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

5. move(int from, int to, int n)

Move n items from one location to another. The from and to scopes must exist.

For example, to move the first 3 items to the end of the list:

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

6. remove(int index, int count = 1)

Removes the count item at index from the model.

7. set(int index, jsobject dict)

Change the item at index in the list model with the value in the dict.

If index is equal to count() , append the new item to the list. Otherwise, index must be an element in the list.

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

8. setProperty(int index, string property, variant value)

Change the property of the item at index in the list model to value. index must be an element in the list.

fruitModel.setProperty(3, “cost”, 5.95)

9. sync()

After modifying a list model from a job script, write any unsaved changes to the list model.

The benefits of this article,Fees to receive Qt development learning materials package, technical video, including (C++ language foundation, introduction to Qt programming, QT signal and slot mechanism, QT interface development – Image drawing, QT network, QT database programming, QT project combat, QT embedded development, Quick module, etc.) ↓↓↓↓↓↓See below↓↓Click at the bottom of the article to receive the fee↓↓