I have been using a DelegateModel and DelegateModelGroup to only show certain items of a List Model in my delegate. The process is essentially the same as the process described in the first answer to this question. The code for the DelegateModel is below.
DelegateModel {
id: displayDelegateModel
delegate: mMissionDelegate
model: mMissionModel
groups: [
DelegateModelGroup {
includeByDefault: false
name: "todaysMissions"
}
]
filterOnGroup: "todaysMissions"
Component.onCompleted: {
updateMissions()
}
}
I am using this so that only 3 random elements from a ListModel are shown in a delegate at once. I then use a function to update these once a timer from c++ times out and emits a signal so a new 3 elements are used. Here is the code for the updating function and he connection with c++.
Connections{
target: FlashingTimer
function onCallUpdateMissions(){
updateMissions();
}
}
function updateMissions(){
var rowCount = mMissionModel.count;
mArray = [];
displayDelegateModel.items.remove(0,displayDelegateModel.items.count);
for(let i =0;i < rowCount;i++ ) {
let entry = mMissionModel.get(i);
mArray.push(entry)
}
let arr = mArray.sort(() => Math.random() - Math.random()).slice(0, 3)
displayDelegateModel.items.insert(arr[0], "todaysMissions");
displayDelegateModel.items.insert(arr[1], "todaysMissions");
displayDelegateModel.items.insert(arr[2], "todaysMissions");
}
At the start, it automatically calls the function with Component.onCompleted as well. My problem is that I cannot figure out how to remove everything from the group before I switch them out. I thought that the items.remove line would do it, but even though the items.count becomes zero, the items still appear in the delegate and the items.insert just adds to to the bottom (so 6 delegates are visible).
Does anyone know a way I could do this, if I have a simple syntax or I should be using an entirely different approach?
Advertisement
Answer
I don’t think removing elements from items
group makes any difference, what you need to do is make the filter group as includeByDefault
, then remove items from that group , namely todaysMissions ;
From documentation
items : DelegateModelGroup
This property holds default group to which all new items are added.
filterOnGroup : string
This property holds name of the group that is used to filter the delegate model.
Only items that belong to this group are visible to a view.
By default this is the items group.
note that items are automatically added to the items
group , and that only items in the filtergroup are visible
Here is an example for filtering GridView
:
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
ListModel {
id: lmodel
ListElement {
title: "This is visible"
isVisible: true
}
ListElement {
title: "This is NOT visible"
isVisible: false
}
ListElement {
title: "This is visible"
isVisible: true
}
ListElement {
title: "This is visible"
isVisible: true
}
ListElement {
title: "This is NOT visible"
isVisible: false
}
}
Rectangle {
width: parent.width; height: parent.height
DelegateModel {
id: visualModel
model: lmodel
groups: [
DelegateModelGroup {
includeByDefault: true
name: "visibleItems"
}
]
filterOnGroup: "visibleItems"
function filterModeView(){
for( var i = 0;i < items.count;i++ ) {
var element = items.get(i).model;
if((element.isVisible !== true)) {
items.removeGroups(i, 1, "visibleItems");
}
}
}
Component.onCompleted: filterModeView()
delegate: Rectangle {
id: item
color: "gold"
border.color: "black"
border.width: 1
height: visible ? 150 : 0
width: visible ? 250 : 0
Text {
// Show indices both in visibleItems filterGroup and items group!
text: {
var text = "Name: " + title
if (item.DelegateModel.inVisibleItems)
text += " (" + item.DelegateModel.visibleItemsIndex + ")" + "[" + item.DelegateModel.itemsIndex + "]"
return text;
}
}
}
}
GridView {
anchors.fill: parent
model: visualModel
cellHeight: 160
cellWidth: 260
}
}
}