是否可以在QML列表视图中仅显示某些索引或一系列索引?
我有一个listmodel,它有一堆我正在重用的信息。是否有可能有一个列表,例如,只显示索引5到8?
答案 0 :(得分:11)
对问题提出纯QML方法会很有趣。这肯定是不短路径,但它是一种解决方案。
该方法基于models
QML模块中提供的DelegateModel
。它读入文档:
DelegateModel类型封装了一个模型和委托 为模型中的项目实例化。
通常不需要创建DelegateModel。但是,它可以 当a时操作和访问modelIndex非常有用 QAbstractItemModel子类用作模型。此外, DelegateModel 与Package一起使用与Package一起提供多个视图的委托, 和 DelegateModelGroup对代理项进行排序和过滤。
DelegateModel
实际上是一个功能强大的类型,具有很多功能(有关详细信息,请参阅链接文档)。 DelegateModel
的两个关键属性是groups
和filterOnGroup
。前者基本上是DelegateModelGroup
的列表,它定义了要过滤的项目。后者用于应用特定过滤器,即通过简单地将属性设置为所选组的名称来选择DelegateModelGroup
中包含的特定groups
。
请注意,引用VisualDataModel
或DelegateModel
是相同的,因为第一个是出于兼容性原因提供的(同样适用于VisualDataGroup
wrt 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");
}
}
}
}
}
答案 1 :(得分:2)
是的,有可能。您需要覆盖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 );
答案 2 :(得分:0)
您可以通过在特定条件下将委托可见性设置为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
}
}
}
}
在内存中创建隐藏项目会有一些开销,所以如果处理非常大的模型并只显示其中的一小部分,则不是最佳选择。