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