'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 1:[1]
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.
Solution 2:[2]
If you want a way to do visual filtering, you can have the view's delegate just not draw for items that shouldn't be visible.
Repeater {
model: myList
Text {
text: model.display.someBoolean ? "yes" : "no"
}
delegate: {
visible: model.someBoolean
height: visible ? 30 /* or whatever height */ : 0
// other drawing code here.
}
}
This may have other visual artifacts (for example, if you have alternating row colors based on index, the rows may not alternate properly) but if you want a quick and dirty filter, it works.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | DmitryARN |
| Solution 2 | RAM |
