是否可以仅显示QML列表视图的某些索引?

时间:2015-03-09 11:35:33

标签: qt listview qml

是否可以在QML列表视图中仅显示某些索引或一系列索引?

我有一个listmodel,它有一堆我正在重用的信息。是否有可能有一个列表,例如,只显示索引5到8?

3 个答案:

答案 0 :(得分:11)

对问题提出纯QML方法会很有趣。这肯定是短路径,但它是一种解决方案。

该方法基于models QML模块中提供的DelegateModel。它读入文档:

  

DelegateModel类型封装了一个模型和委托   为模型中的项目实例化。

     

通常不需要创建DelegateModel。但是,它可以   当a时操作和访问modelIndex非常有用   QAbstractItemModel子类用作模型。此外, DelegateModel   与Package一起使用与Package一起提供多个视图的委托,   和 DelegateModelGroup对代理项进行排序和过滤

DelegateModel实际上是一个功能强大的类型,具有很多功能(有关详细信息,请参阅链接文档)。 DelegateModel的两个关键属性是groupsfilterOnGroup。前者基本上是DelegateModelGroup的列表,它定义了要过滤的项目。后者用于应用特定过滤器,即通过简单地将属性设置为所选组的名称来选择DelegateModelGroup中包含的特定groups

请注意,引用VisualDataModelDelegateModel是相同的,因为第一个是出于兼容性原因提供的(同样适用于VisualDataGroup wrt DelegateModelGroup)。

总结一下,可以用这种方式过滤完整QML中的模型:

  1. 创建model作为过滤模型的来源
  2. model投放到VisualDataModel / DelegateModel
  3. 定义VisualDataGroup / DelegateModelGroup(或多个) - includeByDefault设置为false,以避免自动添加所有项目原始模型
  4. 定义填充组的政策
  5. filterOnGroup设置为所选组
  6. 将视图模型设置为VisualDataModel模型
  7. 在下一个示例中,为简单起见,我只是在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
        }
      }
    }
  }

enter image description here

在内存中创建隐藏项目会有一些开销,所以如果处理非常大的模型并只显示其中的一小部分,则不是最佳选择。