【发布时间】:2015-03-09 11:35:32
【问题描述】:
是否可以在 QML 列表视图中仅显示某些索引或一系列索引?
我有一个列表模型,其中包含我正在重用的大量信息。是否可以有一个列表,例如,仅显示索引 5 到 8?
【问题讨论】:
是否可以在 QML 列表视图中仅显示某些索引或一系列索引?
我有一个列表模型,其中包含我正在重用的大量信息。是否可以有一个列表,例如,仅显示索引 5 到 8?
【问题讨论】:
提出一个纯 QML 方法来解决这个问题会很有趣。当然,这不是捷径,但它是一个解决方案。
该方法基于models QML 模块中的DelegateModel。它在文档中写道:
DelegateModel 类型封装了一个模型和委托 为模型中的项目实例化。
通常不需要创建 DelegateModel。然而,它可以 对操作和访问 modelIndex 很有用 QAbstractItemModel 子类用作模型。另外,DelegateModel 与Package一起使用来为多个视图提供代理, 并使用DelegateModelGroup 对委托项目进行排序和过滤。
DelegateModel 确实是一种强大的类型,具有很多功能(有关详细信息,请参阅链接文档)。 DelegateModel 的两个关键属性是 groups 和 filterOnGroup。前者基本上是DelegateModelGroup 的列表,它定义了要过滤或不过滤的项目。后者用于应用特定过滤器,即选择包含在groups 中的特定DelegateModelGroup,只需将属性设置为所选组的名称即可。
请注意,提及VisualDataModel 或DelegateModel 是相同的,因为第一个是出于兼容性原因提供的(同样适用于VisualDataGroup w.r.t. DelegateModelGroup)。
总结一下,可以通过这种方式过滤完整 QML 中的模型:
model 作为过滤模型的来源model 提供给VisualDataModel/DelegateModel VisualDataGroup/DelegateModelGroup(或多个)-将includeByDefault设置为false以避免自动添加原始模型中的所有项filterOnGroup 设置为所选组VisualDataModel 模型在下一个示例中,为简单起见,我只在Component.onCompleted 事件处理程序期间填充组一次。如前所述,应该选择策略,这取决于具体的用例。
在示例中,只有key 角色等于0 的项目被添加到key0 组中,即ListView 中显示的组。上述清单在代码中突出显示。
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Window 2.0
ApplicationWindow {
title: qsTr("DelegateModel test")
width: 200
height: 350
visible: true
ListView {
id: displayListView
anchors.fill: parent
spacing: 5
//
model: displayDelegateModel // 6
}
ListModel { // 1
id: myModel
ListElement { vis: "One"; key: 0; }
ListElement { vis: "two"; key: 1; }
ListElement { vis: "Three"; key: 0; }
ListElement { vis: "Four"; key: 0; }
ListElement { vis: "Five"; key: 1; }
ListElement { vis: "Six"; key: 1; }
ListElement { vis: "Seven"; key: 0; }
}
VisualDataModel {
id: displayDelegateModel
delegate: Rectangle {
anchors.left: parent.left
anchors.right: parent.right
height: 25
color: "steelblue"
Text {
text: vis
anchors.centerIn: parent
font.bold: true
font.pixelSize: 20
}
}
model: myModel // 2
groups: [
VisualDataGroup { // 3
includeByDefault: false // NECESSARY TO AVOID AUTOADDITION
name: "key0"
}
]
filterOnGroup: "key0" // 5
Component.onCompleted: { // 4
var rowCount = myModel.count;
items.remove(0,rowCount);
for( var i = 0;i < rowCount;i++ ) {
var entry = myModel.get(i);
if(entry.key == 0) {
items.insert(entry, "key0");
}
}
}
}
}
【讨论】:
是的,这是可能的。您需要覆盖QSortFilterProxyModel::filterAcceptRow 方法。
MyFilterModel::filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const
{
if ( source_row > 5 && source_row < 8 )
return true;
return false;
}
//...
MyFilterModel *filter = new MyFilterModel();
filter->setSourceMoldel( yourSourceModel );
view->setModel( filter );
【讨论】:
您可以通过在某些条件下将委托可见性设置为 false 来实现:
Grid {
anchors.fill: parent
rows: 4
columns: 5
spacing: 5
Repeater {
model: 20
delegate: Rectangle {
width: 50
height: 50
visible: index >= 5 && index <= 8 // show only certain indices
Text {
anchors.centerIn: parent
text: index
}
}
}
}
在内存中创建隐藏项会产生一些开销,因此如果您处理非常大的模型并仅显示其中的一小部分,则不是最佳选择。
【讨论】:
visible: currentPage == 1 ? index < 6 : index >= 6 之类的东西,其中 currentPage 是根属性。没有警告。刚刚工作。