qmlqt5qabstractitemmodelqsortfilterproxymodel

Filtering / sorting a QAbstractListModel in QML


I have a QAbstractListModel-derived C++ class which contains a list of two types of things, e.g. like this:

class MyList : public QAbstractListModel
{
    Q_OBJECT
public:
    MyList();

    int rowCount(const QModelIndex& parent = QModelIndex()) const override
    {
        return mData.size();
    }

    QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override
    {
        int i = index.row();
        if (i < 0 || i >= mData.size())
            return QVariant(QVariant::Invalid);

        return QVariant::fromValue(mData[i]);
    }

private:
    QList<Something> mData;
};

Suppose the data has a boolean member so that in QML I can do something like this:

Repeater {
    model: myList
    Text {
        text: model.display.someBoolean ? "yes" : "no"
    }
}

My question is very simple. How do I make the list only show items for which someBoolean is true? I.e. how do I filter the list?

I'm aware of QSortFilterProxyModel but the documentation only mentions C++. Do I have to create a QAbstractItemModel* as a Q_PROPERTY of MyList and then set the QML model to it? Like this?

Repeater {
    model: myList.filteredModel

...

class MyList : public QAbstractListModel
{
    Q_OBJECT
    Q_PROPERTY(QAbstractItemModel* filteredModel READ filteredModel ... etc)
public:

Does anyone have any guidance or examples?

Note: I've seen this question. It doesn't answer the question and doesn't appear to be about QML anyway despite the title.


Solution

  • You need to subclass QSortFilterProxyModel and make a filtering inside it as documentation suggests. Then you need to assign the QSortFilterProxyModel object to the required QML object. This is how the QML object will recieve the filtered data.