I have a QML ListModel like follows:
ListModel {
id: myListModel
ListElement {myId: "1", myValue = "12"}
ListElement {myId: "2", myValue = "0"}
...
ListElement {myId: "21", myValue = "123"}
}
Then I have some simple QML labels like follows:
Label {
id: myLabel1
property int labelInt: 1
text: myListModel.get().myValue; //Here is my problem!
}
Label {
id: myLabel2
property int labelInt: 22
text: myListModel.get().myValue; //Here is my problem!
}
My problem is to fill that brackets in myListMode.get().myValue. In fact I need a condition: if myListModel has some myId that equals my current labelInt, then return me the corresponding myId, otherwise leave empty space:
I tried with:
myListModel.get(myListModel.get(myId = labelInt).myId).myValue;
but I am not sure It's the proper way.
Can you help me? Thank you
I have a QML ListModel like follows:
ListModel {
id: myListModel
ListElement {myId: "1", myValue = "12"}
ListElement {myId: "2", myValue = "0"}
...
ListElement {myId: "21", myValue = "123"}
}
Then I have some simple QML labels like follows:
Label {
id: myLabel1
property int labelInt: 1
text: myListModel.get().myValue; //Here is my problem!
}
Label {
id: myLabel2
property int labelInt: 22
text: myListModel.get().myValue; //Here is my problem!
}
My problem is to fill that brackets in myListMode.get().myValue. In fact I need a condition: if myListModel has some myId that equals my current labelInt, then return me the corresponding myId, otherwise leave empty space:
I tried with:
myListModel.get(myListModel.get(myId = labelInt).myId).myValue;
but I am not sure It's the proper way.
Can you help me? Thank you
Share Improve this question asked May 15, 2017 at 8:49 AleAle 3052 gold badges8 silver badges18 bronze badges 7-
Try
ListElement {myId: "1", myValue: "12"}
-:
instead of=
. Also, see here for how to search thorough a list model: stackoverflow./questions/41991438/… – dtech Commented May 15, 2017 at 9:34 - Doesn't work :-( – Ale Commented May 15, 2017 at 9:38
-
Will the
myId
that you query, vary often? Will the content of theListModel
change often? – derM Commented May 15, 2017 at 10:09 - Yes, it's always different! – Ale Commented May 15, 2017 at 10:28
-
1
During the runtime of the programm: Will data be appended and/or removed from the
ListModel
? Will, for one entry in theListModel
the values be constant over time, may all change, or is at leastmyId
constant? – derM Commented May 15, 2017 at 10:51
2 Answers
Reset to default 1If you speed is your desire, you should map you entries to the myId
.
In QML you can do this with a bination of a Instantitator
and a JSObject
.
property var tracker: ({})
Instantiator {
model: tm
delegate: QtObject {
id: instDummy
property QtObject modelData: model
property string __oldID
property string myID: model.myID
onMyIDChanged: {
if (myID && __oldID !== myID) {
delete tracker[__oldID]
__oldID = myID
tracker[__oldID] = instDummy
console.log('changed', Object.keys(tracker))
}
}
Component.onCompleted: {
__oldID = myID
}
Component.onDestruction: {
console.log(__oldID, modelData.myID, delete tracker[__oldID])
console.log('removed', Object.keys(tracker))
}
}
}
Explanation:
The Instantiator
creates a QtObject
for each entry in the model. This QtObject
stores a reference to the model data of the entry. The two properties myID
and __oldID
are used to keep the Map (JSObject) tracker
up to date.
myID
is bound to the model.myID
so, whenever this would change it would trigger the signal on myID
changed. Now I need to change the key in the map from the old value to the new value. Therefore I delete the entry with the key __oldID
, then I update __oldID
to the new myID
and add the object back into the map, with the new key.
I don't want __oldID
to be bound, therefore I assign it in Component.onCompleted
.
When the entry is removed, I remove the object and the reference from the Map
as well, so I keep my map as clean as possible.
When a new entry is added, the Instantiator
will automatically add a new QtObject
for this.
Now you can query your myID
in O(1)
with tracker[myID]
. The Instantiator
takes care that all changes will be tracked. It only changes, when there is a change to the model in the specific row.
Note that this method will take a toll on your memory, as it will basically duplicate your model in the hashmap.
To avoid this, you might implement a ProxyModel
in C++, e.g. based on the QIdentityProxyModel
to which you add a mapping of the myID
and the actuall model index. Handle the dataChanged
-signal to keep that map up-to-date.
PS: I expect that at least the myID
is unique. Otherwise like this, you might lose some references. Use buckets then, to keep multiple entries in the map for shared myID
's
You need to loop through your model to find the element.
Example:
import QtQuick 2.2
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
ApplicationWindow {
function findElement(myModel, myId) {
for(var i = 0; i < myModel.count; i++) {
var element = myModel.get(i);
if(myId == element.myId) {
console.log("Found element: ", i);
return element.myId;
}
}
return "";
}
id: window
visible: true
TableView {
y: 70
width: 500
TableViewColumn {
role: "myId"
title: "myId"
width: 100
}
TableViewColumn {
role: "myValue"
title: "myValue"
width: 100
}
model: myListModel
ListModel {
id: myListModel
ListElement
{
myId: "1"
myValue: "12"
}
ListElement
{
myId: "2"
myValue: "0"
}
ListElement
{
myId: "21"
myValue: "123"
}
}
}
Label
{
id: myLabel1
property int labelInt: 1
x: 0
text: findElement(myListModel, labelInt);
}
Label
{
id: myLabel2
property int labelInt: 22
x: 100
text: findElement(myListModel, labelInt);
}
}
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745090013a4610638.html
评论列表(0条)