【问题标题】:Working with delegate model and delegate model group dynamically QML?动态使用委托模型和委托模型组 QML?
【发布时间】:2020-12-04 15:39:31
【问题描述】:

我一直在使用 DelegateModel 和 DelegateModelGroup 来仅在我的委托中显示列表模型的某些项目。该过程与this question的第一个答案中描述的过程基本相同。 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 个委托可见)。

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

【问题讨论】:

    标签: javascript qt delegates qml


    【解决方案1】:

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

    来自文档

    项目:DelegateModelGroup

    此属性保存所有新项目添加到的默认组。

    filterOnGroup:字符串

    此属性包含用于过滤的组的名称 委托模型。

    只有属于该组的项目对视图可见。

    默认情况下这是项目组。

    请注意,项目会自动添加到 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
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 我将尝试改用 QSortFilterProxyModel。但是,当我阅读文档时,并不清楚将其与用 QML 编写的模型连接起来,所有示例都涉及过滤/排序 c++ 模型。
      • 它仅用于 C++ 模型。如果你使用 QML 模型,可以试试this
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-30
      • 1970-01-01
      相关资源
      最近更新 更多