如何将元素添加到DelegateModelGroup,具体取决于属性

问题描述:

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

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++解决这个问题,但我不想,除非必要。

问题是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 
      } 
     } 
    } 
} 
+0

太棒了!谢谢。我认为这是我可以建立的基础。我只需要添加功能,即setGroups()将被调用,当一个元素被改变(因此可能被踢出或添加到组),但这是一个好的开始! – derM

对于那些有兴趣的人,用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')]) 
    } 
}