如何根据属性将元素添加到 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的主要内容,如果未能解决你的问题,请参考以下文章
如何在angularjs中动态地将样式属性添加到具有ng-class的元素
Vue 模板:如何自动将自定义属性添加到具有 v-on:click 指令的元素