如何根据属性将元素添加到 DelegateModelGroup

Posted

技术标签:

【中文标题】如何根据属性将元素添加到 DelegateModelGroup【英文标题】:How to add elements to a DelegateModelGroup depending on a property 【发布时间】:2016-09-29 12:55:32 【问题描述】:

我有一个 ListModel 和一个 DelegateModel、一个 ListView 和 3 个按钮。 DelegateModel 有一个组:myGroup 通过单击前两个按钮,我将具有不同属性的元素添加到 ListModel,然后将用于添加它们或不将它们添加到 myGroup。第三个按钮用于切换过滤器。

ListModel 
    id: rootModel



DelegateModel 
    id: visualModel
    model: rootModel
    groups: [DelegateModelGroup  name: 'myGroup' ]

    delegate: Rectangle 
        width: model.width
        height: model.height
        color: model.color
        border.width: 1

        Component.onCompleted: DelegateModel.inMyGroup = Qt.binding(function() return width == 80)
    


ListView 
    width: 300
    height: 480
    model: visualModel


Rectangle 
    id: b1
    x: 350
    width: 100
    height: 50
    color: 'lightsteelblue'
    Text 
        anchors.centerIn: parent
        text: 'add 80'
    

    MouseArea 
        anchors.fill: parent
        onClicked: rootModel.append(  width: 80, height: 30, color: 'steelblue' )
    


Rectangle 
    id: b2
    x: 350
    y: 70
    width: 100
    height: 50
    color: 'violet'
    Text 
        anchors.centerIn: parent
        text: 'add 50'
    

    MouseArea 
        anchors.fill: parent
        onClicked: rootModel.append(  width: 50, height: 30, color: 'violet' )
    

Rectangle 
    id: b3
    x: 350
    y: 140
    width: 100
    height: 50
    color: 'green'
    Text 
        anchors.centerIn: parent
        text: 'filter'
    

    MouseArea 
        anchors.fill: parent
        property bool toggle: false
        onClicked: 
            visualModel.filterOnGroup = toggle ? '' : 'myGroup'
            toggle = !toggle
        
    

到目前为止一切顺利,只要不设置过滤器,我可以将这两种类型的元素添加到模型中,然后我可以过滤。 但是,只要我设置了过滤器,我就无法将元素添加到模型(组)中。这很明显,默认情况下不添加元素,所以组件没有完成,也没有添加到组中,直到我再次取消设置过滤器,所有待处理的元素都被实例化,完成,最后添加。

因此,我寻找另一种方法来根据属性自动将元素添加到组中,或者排除它们。

我知道,我可以设置includeByDefault: true,然后在它们被实例化一次后将它们扔掉。虽然这解决了这个特定问题,但它并没有解决下一个问题,我将更改属性,因此将其从组中删除,然后再将其更改回来。在组件再次实例化之前它不会重新出现。

哦,我知道,我可以用 C++ 解决这个问题,但我不想这样做,除非有必要。

【问题讨论】:

【参考方案1】:

对于那些对此感兴趣的人,在 user2436719 的提示下,我能够破解这个模型。 它是一个 ListModel,例如两个 DelegateModel,根据 listmodel 的角色将元素添加到组中。

ListModel
    id: rootModel
    onCountChanged: setGroups(count - 1)
    onDataChanged: setGroups(arguments[0].row)
    property DelegateModel sub1:
        DelegateModel 
            id: subModel1
            model: rootModel
            groups: [
                DelegateModelGroup  name: 'myGroup' ,
                DelegateModelGroup  name: 'notMyGroup' 
            ]
            delegate: Rectangle 
                width: model.width
                height: model.height
                color: model.color
                border.width: 1
            
            filterOnGroup: (root.toggle ? 'myGroup' : 'notMyGroup')
        
    property DelegateModel sub2:
        DelegateModel 
            id: subModel2
            model: rootModel
            groups: [
                DelegateModelGroup  name: 'myGroup' ,
                DelegateModelGroup  name: 'notMyGroup' 
            ]
            delegate: Rectangle 
                radius: 5
                width: model.width
                height: model.height
                color: model.color
                border.width: 1

                Text 
                    anchors.centerIn: parent
                    text: DelegateModel.groups.toString()
                
            
            filterOnGroup: (root.toggle ? 'myGroup' : 'notMyGroup')
        

    function setGroups(index) 
        console.log('set Groups for', index)
        var i = get(index)
        subModel1.items.setGroups(index, 1, ['items', (i.width === 80 ? 'myGroup' : 'notMyGroup')])
        subModel2.items.setGroups(index, 1, ['items', (i.width !== 80 ? 'myGroup' : 'notMyGroup')])
    

【讨论】:

【参考方案2】:

问题是DelegateModel.inMyGroup = Qt.binding(function() return width == 80) 仅在显示对象后才被评估。但是当过滤器打开时,如果添加了一个元素,它不属于myGroup组,所以它不会显示并且永远没有机会评估条件。

这是一个快速修复,我添加了一个每次添加元素时都会执行的函数。默认组似乎是'items' 而不是''

Window 
    visible: true
    width: 640
    height: 480
    property bool toggle: true


    ListModel
        id: rootModel
        onCountChanged: visualModel.setGroups()
    

    DelegateModel 
        id: visualModel
        model: rootModel
        filterOnGroup: toggle ? 'items' : 'myGroup'
        groups: [DelegateModelGroup  id: myGroup; name: 'myGroup' ]

        function setGroups() 
            var newItem = rootModel.get(rootModel.count - 1)
            var groups;
            if (newItem.width == 80)
                groups = ['items', 'myGroup'];
            else
                groups = ['items'];
            
            items.setGroups(rootModel.count - 1, 1, groups)
        

        delegate: Rectangle 
            width: model.width
            height: model.height
            color: model.color
            border.width: 1
        
    

    ListView 
        width: 300
        height: 480
        model: visualModel
    

    Rectangle 
        id: b1
        x: 350
        width: 100
        height: 50
        color: 'lightsteelblue'
        Text 
            anchors.centerIn: parent
            text: 'add 80'
        

        MouseArea 
            anchors.fill: parent
            onClicked: rootModel.append(  width: 80, height: 30, color: 'steelblue' )
        
    

    Rectangle 
        id: b2
        x: 350
        y: 70
        width: 100
        height: 50
        color: 'violet'
        Text 
            anchors.centerIn: parent
            text: 'add 50'
        

        MouseArea 
            anchors.fill: parent
            onClicked: rootModel.append(  width: 50, height: 30, color: 'violet' )
        
    
    Rectangle 
        id: b3
        x: 350
        y: 140
        width: 100
        height: 50
        color: 'green'
        Text 
            anchors.centerIn: parent
            text: 'filter'
        

        MouseArea 
            anchors.fill: parent
            onClicked: 
                toggle = !toggle
            
        
    

【讨论】:

太棒了!谢谢你。我认为这是我可以建立的东西。我只需要添加功能,当元素更改时(因此可能会被踢出或添加到组中)将调用 setGroups() 但这是一个好的开始!

以上是关于如何根据属性将元素添加到 DelegateModelGroup的主要内容,如果未能解决你的问题,请参考以下文章

如何根据包含的时间属性将子标题添加到 div?

如何在angularjs中动态地将样式属性添加到具有ng-class的元素

Vue 模板:如何自动将自定义属性添加到具有 v-on:click 指令的元素

如何使用循环根据条件向html标签添加属性

将 HTML5 占位符属性添加到 Spring 3.0 表单输入元素

如何将“类”添加到宿主元素?