Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
692 views
in Technique[技术] by (71.8m points)

qt - Is it possible to show only certain indexes of a QML listview?

Is it possible to show only certain indexes or a range of indexes in QML listviews?

I have a listmodel that has a bunch of info that I am reusing. Would it be possible to have a list showing, for example, only indices 5 to 8?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It would be interesting to present a pure QML approach to the problem. This is not the shorted path, for sure, but it is a solution.

The approach is based on the DelegateModel available in the models QML module. It reads in the documentation:

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 is really a powerful type with a lot of functionalities (see the linked documentation for details). Two key properties of DelegateModel are groups and filterOnGroup. The former is basically a list of DelegateModelGroup which defines the items to be filtered or not. The latter is used to apply a specific filter, i.e. choose a specific DelegateModelGroup contained in groups, by simply setting the property to the name of the chosen group.

Note that referring to VisualDataModel or DelegateModel is the same since the first is provided for compatibility reasons (the same applies to VisualDataGroup w.r.t. DelegateModelGroup).

Summing up, it is possible to filter a model in full QML in this way:

  1. Create a model as a source of filtered models
  2. Feed the model to a VisualDataModel/DelegateModel
  3. Define a VisualDataGroup/DelegateModelGroup (or more than one) - includeByDefault set to false to avoid automatic addition of all items from the original model
  4. Define policies to populate the groups
  5. Set filterOnGroup to the chosen group
  6. Set the view model to the VisualDataModel model

In the next example, for simplicity, I just populate the group once, during the Component.onCompleted event handler. As said, policies should be chosen and that's depends on the specific use case.

In the example only the items with key role equal to 0 are added to the group key0 which is the one shown in the ListView. The checklist described above is highlighted in the code.

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");
                }
            }
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...