QSortFilterProxyModel OR connection
-
Hi everyone,
I am currently trying to use the QSortFilterProxyModel on my tableview.
I already wrote a new class to filter over several columns.
The big Problem is, that I want to filter two columns with two regexpressions, but show them BOTH!
e.g.:name occupation
petra programmer
carla analystIf I filter the "name" column for petra, and the "occupation" column for analyst, both should be shown.
I currently have no means to achieve this, because each filter is built on the other... does anybody have suggestions?regards
-
Thank you very much for your answer. I will look into the Libqxt library.
Does it really provide the solution for my problem? As far as I understand it a single filter filtering over several columns is still an AND connection between the RegExpressions, or am I wrong?
Thank you for your help. -
Good one. I think you are right. Perhaps you can use it as the base of your own filter though, and make it an OR filter. Might be a nice patch for the Qxt one as well (optional, of course), as that really adds new functionality while the AND one can be achieved using a stack of standard QSortFilterProxyModels.
-
Well, i solved it myself. I had to override QSortFilterProxyModel's filterAcceptsRow() method.In this method all i have to do is loop through on desired columns that I wanted to filter and apply Regular-expression on them.If columns contains the filtered text then return True else return False.
If this is wrong then please update it.
python code:
@def filterAcceptsRow(self,sourceRow,sourceParent):
#say you have 5 columns
for column in range(self.sourceModel().columnCount()):
index=self.sourceModel().index(sourceRow,column,sourceParent)
data=self.sourceModel().data(index,QtCore.Qt.ItemDataRole.DisplayRole)
if column in [0,1,2]:#filter only the desired columns
if self.filterRegExp().indexIn(data)==-1:
return False
return True
@Thanks.
-
Well sounds about right...
I Used the "Mysortfilterproxymodel" from the Qt Examples as my first goto... so just for completion some of it is still in here;Mysortfilterproxymodel.h:
@
#include <QDate>
#include <QSortFilterProxyModel>//! [0]
class MySortFilterProxyModel : public QSortFilterProxyModel
{
Q_OBJECTpublic:
//Example for implementing it(no declarations) :
//
// myproxy=new MySortFilterProxyModel();
// myproxy->setSourceModel(sourcemodel);
// QRegExp regExp("NuMbeR1|Test3122|Dethklok");
// myproxy->setFilterRegExp(regExp);
// ui->view->setModel(myproxy);
// this implementation will now filter the given rows (not dynamicly given)
// after the regular [removed]NuMber1 OR Test3122 etc. etc.)MySortFilterProxyModel(QObject *parent = 0);
//these are just included for purposes of completion,
//they should be safe to remove.
QDate filterMinimumDate() const { return minDate; }
void setFilterMinimumDate(const QDate &date);QDate filterMaximumDate() const { return maxDate; }
void setFilterMaximumDate(const QDate &date);
//thill here not really nessecaryprotected:
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
bool lessThan(const QModelIndex &left, const QModelIndex &right) const;private:
bool dateInRange(const QDate &date) const;
QDate minDate;
QDate maxDate;
};
//! [0]#endif
@Mysortfilterproxymodel.cpp:
@#include <QtGui>
#include "mysortfilterproxymodel.h"
//! [0]
MySortFilterProxyModel::MySortFilterProxyModel(QObject *parent)
: QSortFilterProxyModel(parent)
{
}
//! [0]//! [1]
void MySortFilterProxyModel::setFilterMinimumDate(const QDate &date)
{
minDate = date;
invalidateFilter();
}
//! [1]//! [2]
void MySortFilterProxyModel::setFilterMaximumDate(const QDate &date)
{
maxDate = date;
invalidateFilter();
}
//! [2]//! [3]
bool MySortFilterProxyModel::filterAcceptsRow(int sourceRow,
const QModelIndex &sourceParent) const
{
//Depending on how many rows have to be filtered...
// 1. add new Indiezes
// 2. select the concerned rows
// 3.add them to your source model via return(just follow the example below)
QModelIndex index0 = sourceModel()->index(sourceRow, 5, sourceParent);
QModelIndex index1 = sourceModel()->index(sourceRow, 15, sourceParent);
QModelIndex index2 = sourceModel()->index(sourceRow, 0, sourceParent);return (sourceModel()->data(index0).toString().contains(filterRegExp())
|| sourceModel()->data(index1).toString().contains(filterRegExp()))
&& dateInRange(sourceModel()->data(index2).toDate());
}
//! [3]//! [4] //! [5]
bool MySortFilterProxyModel::lessThan(const QModelIndex &left,
const QModelIndex &right) const
{
QVariant leftData = sourceModel()->data(left);
QVariant rightData = sourceModel()->data(right);
//! [4]//! [6]
if (leftData.type() == QVariant::DateTime) {
return leftData.toDateTime() < rightData.toDateTime();
} else {
QRegExp emailPattern = new QRegExp("([\w\.]@[\w\.]*)");QString leftString = leftData.toString(); if(left.column() == 1 && emailPattern->indexIn(leftString) != -1) leftString = emailPattern->cap(1); QString rightString = rightData.toString(); if(right.column() == 1 && emailPattern->indexIn(rightString) != -1) rightString = emailPattern->cap(1); return QString::localeAwareCompare(leftString, rightString) < 0;
}
}
//! [5] //! [6]//! [7]
bool MySortFilterProxyModel::dateInRange(const QDate &date) const
{
return (!minDate.isValid() || date > minDate)
&& (!maxDate.isValid() || date < maxDate);
}
//! [7]
@Hope it helps.
Sorry don't have too much time right now(obviously) but if there are other problems I will get to it as soon as possible.
I wish you a very happy Christmas and all good things in 2012!