The ListModel element defines a free-form list data source. More...
The ListModel is a simple hierarchy of elements containing data roles. The contents can be defined dynamically, or explicitly in QML:
For example:
import Qt 4.7 ListModel { id: fruitModel ListElement { name: "Apple" cost: 2.45 } ListElement { name: "Orange" cost: 3.25 } ListElement { name: "Banana" cost: 1.95 } }
Roles (properties) must begin with a lower-case letter. The above example defines a ListModel containing three elements, with the roles "name" and "cost".
Values must be simple constants - either strings (quoted and optionally within a call to QT_TR_NOOP), bools (true, false), numbers, or enum values (like Text.AlignHCenter).
The defined model can be used in views such as ListView:
import Qt 4.7 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 } }
It is possible for roles to contain list data. In the example below we create a list of fruit attributes:
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" } ] } }
The delegate below displays all the fruit attributes:
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 } } } } }
The content of a ListModel may be created and modified using the clear(), append(), set() and setProperty() methods. For example:
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) } } }
Note that when creating content dynamically the set of available properties cannot be changed once set. Whatever properties are first added to the model are the only permitted properties in the model.
ListModel can be used together with WorkerScript access a list model from multiple threads. This is useful if list modifications are synchronous and take some time: the list operations can be moved to a different thread to avoid blocking of the main GUI thread.
Here is an example that uses WorkerScript to periodically append the current time to a list model:
import Qt 4.7 ListView { width: 200 height: 300 model: listModel delegate: Component { Text { text: time } } ListModel { id: listModel } WorkerScript { id: worker source: "dataloader.js" } Timer { id: timer interval: 2000; repeat: true running: true triggeredOnStart: true onTriggered: { var msg = {'action': 'appendCurrentTime', 'model': listModel}; worker.sendMessage(msg); } } }
The included file, dataloader.js, looks like this:
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 } }
The application's Timer object periodically sends a message to the worker script by calling WorkerScript::sendMessage(). When this message is received, WorkerScript.onMessage() is invoked in dataloader.js, which appends the current time to the list model.
Note the call to sync() from the WorkerScript.onMessage() handler. You must call sync() or else the changes made to the list from the external thread will not be reflected in the list model in the main thread.
If a list model is to be accessed from a WorkerScript, it cannot contain list data. So, the following model cannot be used from a WorkerScript because of the list contained in the "attributes" property:
ListModel { id: fruitModel ListElement { name: "Apple" cost: 2.45 attributes: [ ListElement { description: "Core" }, ListElement { description: "Deciduous" } ] } }
In addition, the WorkerScript cannot add any list data to the model.
See also Data Models, Threaded ListModel example, and QtDeclarative.
read-onlycount : int |
The number of data entries in the model.
object ListModel::get ( int index ) |
Returns the item at index in the list model.
fruitModel.append({"cost": 5.95, "name":"Jackfruit"}) fruitModel.get(0).cost
The index must be an element in the list.
Note that properties of the returned object that are themselves objects will also be models, and this get() 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"
See also append().
ListModel::insert ( int index, jsobject dict ) |
Moves n items from one position to another.
The from and to ranges must exist; for example, to move the first 3 items to the end of the list:
fruitModel.move(0, fruitModel.count - 3, 3)
See also append().
ListModel::set ( int index, jsobject dict ) |
Changes the item at index in the list model with the values in dict. Properties not appearing in dict are left unchanged.
fruitModel.set(3, {"cost": 5.95, "name":"Pizza"})
The index must be an element in the list.
See also append().
Changes the property of the item at index in the list model to value.
fruitModel.setProperty(3, "cost", 5.95)
The index must be an element in the list.
See also append().
Writes any unsaved changes to the list model after it has been modified from a worker script.