是否可以只显示 QML 列表视图的某些索引?
Is it possible to show only certain indexes of a QML listview?
是否可以在 QML 列表视图中仅显示某些索引或一系列索引?
我有一个列表模型,其中包含大量我正在重复使用的信息。是否可以有一个列表显示,例如,仅索引 5 到 8?
是的,这是可能的。您需要覆盖 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
}
}
}
}
在内存中创建隐藏项目会产生一些开销,因此如果您处理非常大的模型并且只显示其中的一小部分,则不是最佳选择。
提出一个纯 QML 方法来解决这个问题会很有趣。当然,这不是 短路,但它是一个解决方案。
该方法基于 models
QML 模块中可用的 DelegateModel
。它在文档中读取:
The DelegateModel type encapsulates a model and the delegate that will
be instantiated for items in the model.
It is usually not necessary to create a DelegateModel. However, it can
be useful for manipulating and accessing the modelIndex when a
QAbstractItemModel subclass is used as the model. Also, DelegateModel
is used together with Package to provide delegates to multiple views,
and with DelegateModelGroup to sort and filter delegate items.
DelegateModel
确实是一个功能强大的类型(有关详细信息,请参阅链接文档)。 DelegateModel
的两个关键属性是 groups
and filterOnGroup
。前者基本上是一个 DelegateModelGroup
的列表,它定义了要过滤或不过滤的项目。后者用于应用特定的过滤器,即通过简单地将 属性 设置为所选组的名称,选择包含在 groups
中的特定 DelegateModelGroup
。
请注意,引用 VisualDataModel
或 DelegateModel
是相同的,因为第一个是出于兼容性原因提供的(同样适用于 VisualDataGroup
w.r.t。DelegateModelGroup
).
总而言之,可以通过这种方式在完整的 QML 中过滤模型:
- 创建一个
model
作为筛选模型的来源
- 将
model
喂给 VisualDataModel
/DelegateModel
- 定义一个
VisualDataGroup
/DelegateModelGroup
(或多个)- includeByDefault
设置为false
以避免自动添加all 个来自原始模型的项目
- 定义填充组的策略
- 将
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");
}
}
}
}
}
是否可以在 QML 列表视图中仅显示某些索引或一系列索引?
我有一个列表模型,其中包含大量我正在重复使用的信息。是否可以有一个列表显示,例如,仅索引 5 到 8?
是的,这是可能的。您需要覆盖 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
}
}
}
}
在内存中创建隐藏项目会产生一些开销,因此如果您处理非常大的模型并且只显示其中的一小部分,则不是最佳选择。
提出一个纯 QML 方法来解决这个问题会很有趣。当然,这不是 短路,但它是一个解决方案。
该方法基于 models
QML 模块中可用的 DelegateModel
。它在文档中读取:
The DelegateModel type encapsulates a model and the delegate that will be instantiated for items in the model.
It is usually not necessary to create a DelegateModel. However, it can be useful for manipulating and accessing the modelIndex when a QAbstractItemModel subclass is used as the model. Also, DelegateModel is used together with Package to provide delegates to multiple views, and with DelegateModelGroup to sort and filter delegate items.
DelegateModel
确实是一个功能强大的类型(有关详细信息,请参阅链接文档)。 DelegateModel
的两个关键属性是 groups
and filterOnGroup
。前者基本上是一个 DelegateModelGroup
的列表,它定义了要过滤或不过滤的项目。后者用于应用特定的过滤器,即通过简单地将 属性 设置为所选组的名称,选择包含在 groups
中的特定 DelegateModelGroup
。
请注意,引用 VisualDataModel
或 DelegateModel
是相同的,因为第一个是出于兼容性原因提供的(同样适用于 VisualDataGroup
w.r.t。DelegateModelGroup
).
总而言之,可以通过这种方式在完整的 QML 中过滤模型:
- 创建一个
model
作为筛选模型的来源 - 将
model
喂给VisualDataModel
/DelegateModel
- 定义一个
VisualDataGroup
/DelegateModelGroup
(或多个)-includeByDefault
设置为false
以避免自动添加all 个来自原始模型的项目 - 定义填充组的策略
- 将
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");
}
}
}
}
}