change QSortFilterProxyModel behaviour for multiple column filtering
-
Well let's say we have a
QSortFilterProxyModel
installed on aQTableView
and two (or more)QLineEdit
for filtering the view (based on the text of theseQLineEdit
s)
In our View we have slot that tell us the string of lineedits and the current column that we want
Something like this :void onTextChange(int index, QString ntext) { filter.setFilterKeyColumn(index); filter.setFilterRegExp(QRegExp(ntext, Qt::CaseInsensitive)); }
On the first column we have names in the second we have year of birthday now we enter a year for column 2 (for example 1985) till now filtering is ok but when we switch to first lineedit and enter name (for example john) the previous filtering based on year will reset.
How could we change this behaviour for our customQSortFilterProxyModel
?
(Actually when we change the filter keycolumn the filtermodel must filter existing view not reset it) -
This is some old code I had. Looking at it there is a lot of room for optimisation but it does the job: http://pastebin.com/7yUnvW39
use
setDateRangeFilter
andsetRegExpFilter
to set the filters you want -
Most of the solutions I have seen regarding filtering of multiple columns involve subclassing QSortFilterProxyModel, which would likely have a very limited reusability. However, it is quite possible to chain proxy models that filter on different columns, resulting in the conditions being AND'ed.
For example:
QSqlTableModel *m = new QSqlTableModel(db); // setup model QSortFilterProxyModel *nmFilter = new QSortFilterProxyModel(m); nmFilter->setSourceModel(m); nmFilter->setFilterKeyColumn(0); QSortFilterProxyModel *yrFilter = new QSortFilterProxyModel(m); yrFilter.setSourceModel(nmFilter); yrFilter.setFilterKeyColumn(1); QTableView *v = ui->tblPerson; v.setModel(yrFilter); // add slots to setFilterRegExp();
Keep in mind the possible performance implications of chained proxies if you have very large models.
-
- subclass
QSortFilterProxyModel
- get rid of the setFilterKeyColumn() calls
- Instead implement your custom setters of the filter-text for each column.
- In the setter call
QSortFilterProxyModel::invalidate()
everytime the filter-text changes - reimplement
QSortFilterProxyModel::filterAcceptsRow()
and check if theQt::DisplayData
of the column matches your corresponding filter-text. Return true if it does, false otherwise
- subclass
-
@raven-worx said in change QSortFilterProxyModel behaviour for multiple column filtering:
- reimplement
QSortFilterProxyModel::filterAcceptsRow()
and check if theQt::DisplayData
of the column matches your corresponding filter-text. Return true if it does, false otherwise
QSortFilterProxyModel::filterRole()
should be used instead of an arbitraryQt::DisplayRole
.
Alternalively you can ditch it completely and do the same as you did forQSortFilterProxyModel::setFilterKeyColumn()
that's what I did in the paste above@Glenn-Aycock said in change QSortFilterProxyModel behaviour for multiple column filtering:
subclassing QSortFilterProxyModel, which would likely have a very limited reusability
Subclassing QSortFilterProxyModel does not impact reusability at all. It does only if your implementation violates the D part of S.O.L.I.D. OOP principles
- reimplement
-
Sorry for late respond (kind of busy!)
Answer from stackfverflow : http://stackoverflow.com/questions/39488901/change-qsortfilterproxymodel-behaviour-for-multiple-column-filtering -
@IMAN4K said in change QSortFilterProxyModel behaviour for multiple column filtering:
Answer from stackfverflow : http://stackoverflow.com/questions/39488901/change-qsortfilterproxymodel-behaviour-for-multiple-column-filtering
This answer is the typical example that lead people to say
subclassing QSortFilterProxyModel, which would likely have a very limited reusability
It's bad. the proxy model implementation should not depend on the structure of the underlying data in sourceModel