动态使用委托模型和委托模型组 QML?

Working with delegate model and delegate model group dynamically QML?

我一直在使用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 。 DelegateModel 的代码如下。

DelegateModel {
        id: displayDelegateModel
        delegate:  mMissionDelegate
        model: mMissionModel                     
        groups: [
            DelegateModelGroup   {                 
                includeByDefault: false         
                name: "todaysMissions"
            }
        ]
        filterOnGroup: "todaysMissions"     
        Component.onCompleted: {
            updateMissions()
        }
    }

我正在使用它,以便一次仅在委托中显示来自 ListModel 的 3 个随机元素。然后我使用一个函数来更新这些,一旦来自 c++ 的计时器超时并发出一个信号,以便使用新的 3 个元素。这是更新功能的代码以及与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");
}

开始时,它也会自动调用Component.onCompleted函数。 我的问题是,在我将它们关闭之前,我无法弄清楚如何从组中删除所有内容。我认为 items.remove 行可以做到这一点,但即使 items.count 变为零,项目仍然出现在委托中,而 items.insert 只是添加到底部(所以 6 个委托可见)。

如果我有一个简单的语法或者我应该使用完全不同的方法,有人知道我可以做到这一点的方法吗?

我不太熟悉 DelegateModels,即使在您分享的那个 SO link 中,也提到了 DelegateModels 不是最短路径。我建议改用 QSortFilterProxyModel。源模型包含所有列表元素,然后代理模型将过滤掉除随机​​ 3 项之外的所有内容。

这样做的一个好处是定时器代码和随机化都将在 C++ 模型中被隔离。 QML 代码将完全不知道这些。它只会显示模型告诉它的任何内容。

我认为从 items 组中删除元素没有任何区别,您需要做的是将过滤器组设置为 includeByDefault ,然后从该组中删除项目,即 今天的任务 ;

来自文档

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.

请注意,项目会自动添加到 items 组,并且只有过滤器组中的项目可见

这里有一个过滤的例子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
        }
    }
}