Currently, I'm trying to get five items from a QSortFilterProxyModel after I sort the model.
I tried to do this:
void setSourceModel(QAbstractItemModel* source) override
{
QSortFilterProxyModel::setSourceModel(source);
auto* model{sourceModel()};
model->sort(1);
}
and then:
bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override
{
return sourceRow < 5;
}
But that didn't work. I get the first 5 items in the unsorted source model, instead of the first 5 items of the sorted model.
Can someone help me out?
As was stated in the comments, not all models support sorting (The base implementation
QAbstractItemModel::sortis documented to do nothing).Of course, you can override
sortfor your source model. Hopefully, there are at least 2 solutions to solve your problem without bothering with it.1. Using more than 1 level of proxy model:
Instances of
QSortFilterProxyModelcan sort data regardless of what their source model is.setSourceModelso that instead of attachingsourcedirectly tothis, we place anotherQSortFilterProxyModelin between.this->sourceModel()supports sorting.2. With a
QIdentityProxyModel:The above solution builds 3 layers of models:
QSortFilterProxyModelsubclass (filter) >QSortFilterProxyModel(sort) >QAbstractItemModel.Your filter criterion is a little bit special in the sense it does not use the
datamethod from its source. Since this is the case, you may as well extend the definition of what we call filtering and implement the layers as:QIdentityProxyModelsubclass (filter) >QSortFilterProxyModel(sort) >QAbstractItemModel.Inheriting
QIdentityProxyModelwith the below methods should make your model a little bit faster, although the difference may not be visible at all:This is probably all you need. To be safe, you may choose to add the
mapFromSource/mapSelectionFromSourcemethods (and as a bonus, I also includemapToSource/mapSelectionToSourceeven though I really think those last 2 are not needed):