Reputation: 1050
I am currently working on an application that make use of a custom Model as an extension of the Qt Model/View structure. One model, called MyModel, stores an object( say std::vector ) which has a few thousand elements, the data in MyModel are viewed using the standard QTableView. However, the application supports some simple basic filtering of the data viewed in the table, which includes filtering by relevance, upload date, and all.
QSortFilterProxyModel allows model data to be ( sorted and ) filtered based on regular expressions and all but unfortunately the filtering technique defined in bool filterAcceptsRow( int const &, QModelIndex const & ) does not allow a custom functor to be passed such that this functor is used as the filtering function rather than doing the filtering in filterAcceptsRow.
Here's what I'm saying, say one wants to fashion out all even numbers in an already generated multiplication table( 12 x 12 ), currently here's how I think it can be achieved with QSortFilterProxyModel::filterAcceptsRow( ... )
QSortFilterProxyModel::filterAcceptsRow( int source_row, ... )
{
return sourceModel()->data( source_row ).toInt() % 2 == 0;
}
What I want is not only to filter by even numbers, is there a way one can do various filtering by passing different functors to filterAcceptsRow(...)? Like std::sort( , , lambda_expression ) or std::for_each( , , lambda ) etc. so that filtering by relevance, date, time would call the same function but with different functors.
EDIT: I'm sorry for the very bad formatting, my phone can do very less
Upvotes: 2
Views: 1648
Reputation: 3190
According to docs - no, it isn't. The intent of filterAcceptsRow()
is to provide mechanism for customization.
Custom filtering behavior can be achieved by reimplementing the filterAcceptsRow() and filterAcceptsColumn() functions.
So you can implement your custom QSortFilterProxyModel with some modifications that will support functors in filterAcceptsRow()
. For example:
class FilterFunc
{
protected:
const QSortFilterProxyModel * proxy_;
public:
FilterFunc() : proxy_(0) {}
FilterFunc(const QSortFilterProxyModel * p) : proxy_(p) {}
bool operator()(int source_row, const QModelIndex & source_parent) {return true;}
};
class CustomSortFilterProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
FilterFunc filter_;
protected:
virtual bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const {
return filter_(source_row, source_parent);
}
public:
void setFilter(FilterFunc f) {filter_ = f;}
};
Usage:
struct CustomFilter : public FilterFunc
{
bool operator()(int source_row, const QModelIndex & source_parent) {
return proxy_->sourceModel()->data( source_row ).toInt() % 2 == 0;
}
};
//...
CustomSortFilterProxyModel pm;
pm.setFilter(CustomFilter(&pm));
...
//operations that will call filterAcceptsRow()
To use C++11 lambdas - replace FilterFunc
with std::function
, add third argument into filterAcceptsRow()
- object of QSortFilterProxyModel
type, and use std::bind
.
Upvotes: 1