如何根据 属性 向 DelegateModelGroup 添加元素
How to add elements to a DelegateModelGroup depending on a property
我有一个 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++ 解决这个问题,但我不想这样做,除非有必要。
问题是 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
}
}
}
}
对于那些对此感兴趣的人,在 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')])
}
}
我有一个 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++ 解决这个问题,但我不想这样做,除非有必要。
问题是 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
}
}
}
}
对于那些对此感兴趣的人,在 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')])
}
}