Skip to content
Advertisement

Working with delegate model and delegate model group dynamically QML?

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
        }
    }
}
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement