Subclass of QSortFilterProxyModel to filter selected columns
-
Hi Everyone.
I would like to create a subclass of QSortFilterProxyModel , which will filter selected columns. For example columns 1,4 and 6. Can someone help me?
I already implement subclass, and now i want to change filterAcceptsRow function properly. Is this good idea?
The reason why i want to do this is that my program using hiding columns in my qtableview. For example: column 3 and 4 is hidden. When filtering my proxy model columns 3 and 4 are also filtered ,what is incorrect for me.
-
Hi and welcome to devnet,
Shouldn't you rather reimplement filterAcceptColumn ?
-
I found functions:
void QSortFilterProxyModel::setFilterKeyColumn(int column)
{
Q_D(QSortFilterProxyModel);
d->filter_column = column;
d->filter_changed();
}AND
bool QSortFilterProxyModel::filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const
{
Q_UNUSED(source_column);
Q_UNUSED(source_parent);
return true;
}But I have no idea how to start reimplementing. Could you give me some advice?
-
I'm not exactly following what you want to do, but I found this thread useful when I wanted to filter based on multiple columns.
-
I used this code, but this sublclass is usefull for filtering columns with different filter on each of them.
-
Solution to this problem is very important for me. Can someone help me? Please
-
I have a subclass of QHeaderView where I'm hiding columns. Also I implement in QHeaderView signal which sends to my QSortFilterProxyModel hidden columns (as bool, true if not hidden). Slot in QSortFilterProxyModel received that signal .I have about 10 different tables, each of them with different number of columns.
SLOT in QSortFilterProxyModel:
void SortFilterProxyModel::receiveHiddenColumns(bool* ichecked_columns) { checked_columns=ichecked_columns; for(int i=0;i<7;i++){ qDebug()<<"R"<<ichecked_columns[i]; } }
This part of code works and filter only 0 and 1 column:
bool SortFilterProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent) const { QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent); QModelIndex index1 = sourceModel()->index(sourceRow, 1, sourceParent); return (sourceModel()->data(index0).toString().contains(filterRegExp()) || sourceModel()->data(index1).toString().contains(filterRegExp())); // HOW TO RETURN ONLY NOT HIDDEN COLUMNS???? }
I have no idea how to return in filterAcceptsRow() the appropriate columns depending on the received hidden.
-
One solution would be to add a setter to your SortFilterProxyModel that takes a QList<int> that contains the hidden columns, and in filterAccpetsRow, use that list to check what you should do.
-
I have a different question. I declared bool * checked_columns=NULL in header file.
#ifndef SORTFILTERPROXYMODEL_H #define SORTFILTERPROXYMODEL_H #include <QSortFilterProxyModel> #include <QDate> namespace CerSimpleDynamics { namespace Models { class SortFilterProxyModel : public QSortFilterProxyModel { Q_OBJECT public: explicit SortFilterProxyModel(int columns_maximum, QObject *parent = 0); int columns_max; bool * checked_columns=NULL; public slots: void receiveHiddenColumns(bool* ichecked_columns); protected: bool filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent) const; private: }; }
}
#endif // SORTFILTERPROXYMODEL_H
Then i received signal in my SLOT receiveHiddenColumns(). Data is received becouse i see it on the debug screen.
#include "sortfilterproxymodel.h" #include <qdebug.h> namespace CerSimpleDynamics { namespace Models { SortFilterProxyModel::SortFilterProxyModel(int columns_maximum,QObject *parent) : QSortFilterProxyModel(parent) { columns_max=columns_maximum; } void SortFilterProxyModel::receiveHiddenColumns(bool* ichecked_columns) { checked_columns=ichecked_columns; qDebug()<<"RHC-adres checked_columns"<<checked_columns; qDebug()<<"RHC-adres ichecked_columns"<<ichecked_columns; for(int i=0;i<columns_max;i++) { qDebug()<<"RHC"<<checked_columns[i]; } } bool SortFilterProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent) const { qDebug()<<"RFAR-adres checked_columns"<<checked_columns<<endl; QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent); QModelIndex index1 = sourceModel()->index(sourceRow, 1, sourceParent); QModelIndex index2 = sourceModel()->index(sourceRow, 2, sourceParent); bool tab[3]; tab[0]=sourceModel()->data(index0).toString().contains(filterRegExp()); tab[1]=sourceModel()->data(index1).toString().contains(filterRegExp()); tab[2]=sourceModel()->data(index2).toString().contains(filterRegExp()); bool all; for (int i=0;i<3;i++) { all = all || tab[i]; } return all; } }
}
#include "moc_sortfilterproxymodel.cpp"
I wolud like to display my pointer variable (checked_columns) in fuction filterAccpeptsRow() but the pointer shows NULL adress as during declaration in header file. Why initialization in SLOT doesn't work?
-
What makes you think it doesn't work ? Is it called somewhere ?
And why are you using an array of boolean ?
-
I solved this problem, but I have another one now. I received hidden columns as array of boolean.
bool SortFilterProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent) const { bool all=false; bool tab[23]; std::fill(tab, tab + columns_max, false); QModelIndex hidden_columns[23]; int j=0; for(int i=0;i<sourceModel()->columnCount();i++) { if(checked_columns[i]==true) { hidden_columns[j] = sourceModel()->index(sourceRow, i, sourceParent); tab[j]=sourceModel()->data(hidden_columns[j]).toString().contains(filterRegExp()); all = all || tab[j]; j++ ; } } return all; }
It work's but function FilterAcceptsRow() is called as many times as rows in proxy model. I tried to perform a calculation in function only when checking the first row, but it doesnt work.
Do you know some solution to skip calculation in every call of function?
-
Do you mean do your calculation only on row 0 ?
And again: why not just use a QList/QVector<int> to store the hidden columns ?
-
1.Do you mean that hidden column is 1 and unhidden column is 0?
2.What's the difference in implementation between using array of boolean and qlist/qvector?
3. Could you tell me advantege of your solution? -
I don't understand your question 1.
- With a QList of hidden column, you don't need to know the size of the array in your model and you don't need to loop through the complete array to know which columns are hidden or not. You just need to do something like
if (!hiddenColumnList.contains(index.column())) { // do some stuff if column is not hidden }