动态使用委托模型和委托模型组 QML?
Working with delegate model and delegate model group dynamically QML?
我一直在使用DelegateModel and DelegateModelGroup to only show certain items of a List Model in my delegate. The process is essentially the same as the process described in the first answer to 。 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 个委托可见)。
如果我有一个简单的语法或者我应该使用完全不同的方法,有人知道我可以做到这一点的方法吗?
我不太熟悉 DelegateModels,即使在您分享的那个 SO link 中,也提到了 DelegateModels 不是最短路径。我建议改用 QSortFilterProxyModel。源模型包含所有列表元素,然后代理模型将过滤掉除随机 3 项之外的所有内容。
这样做的一个好处是定时器代码和随机化都将在 C++ 模型中被隔离。 QML 代码将完全不知道这些。它只会显示模型告诉它的任何内容。
我认为从 items
组中删除元素没有任何区别,您需要做的是将过滤器组设置为 includeByDefault
,然后从该组中删除项目,即 今天的任务 ;
来自文档
items : DelegateModelGroup
This property holds default group to which all new items are added.
filterOnGroup : string
This property holds name of the group that is used to filter the
delegate model.
Only items that belong to this group are visible to a view.
By default this is the items group.
请注意,项目会自动添加到 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
}
}
}
我一直在使用DelegateModel and DelegateModelGroup to only show certain items of a List Model in my delegate. The process is essentially the same as the process described in the first answer to
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 个委托可见)。
如果我有一个简单的语法或者我应该使用完全不同的方法,有人知道我可以做到这一点的方法吗?
我不太熟悉 DelegateModels,即使在您分享的那个 SO link 中,也提到了 DelegateModels 不是最短路径。我建议改用 QSortFilterProxyModel。源模型包含所有列表元素,然后代理模型将过滤掉除随机 3 项之外的所有内容。
这样做的一个好处是定时器代码和随机化都将在 C++ 模型中被隔离。 QML 代码将完全不知道这些。它只会显示模型告诉它的任何内容。
我认为从 items
组中删除元素没有任何区别,您需要做的是将过滤器组设置为 includeByDefault
,然后从该组中删除项目,即 今天的任务 ;
来自文档
items : DelegateModelGroup
This property holds default group to which all new items are added.
filterOnGroup : string
This property holds name of the group that is used to filter the delegate model.
Only items that belong to this group are visible to a view.
By default this is the items group.
请注意,项目会自动添加到 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
}
}
}