Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QSortFilterProxyModel OR connection
Qt 6.11 is out! See what's new in the release blog

QSortFilterProxyModel OR connection

Scheduled Pinned Locked Moved General and Desktop
9 Posts 3 Posters 4.8k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • 0 Offline
    0 Offline
    010110102
    wrote on last edited by
    #1

    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 analyst

    If 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

    1 Reply Last reply
    0
    • A Offline
      A Offline
      andre
      wrote on last edited by
      #2

      Create a single filter that filters on multiple columns in one go. Libqxt provides one you can use, but it is not hard to create one for yourself either.

      1 Reply Last reply
      0
      • 0 Offline
        0 Offline
        010110102
        wrote on last edited by
        #3

        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.

        1 Reply Last reply
        0
        • A Offline
          A Offline
          andre
          wrote on last edited by
          #4

          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.

          1 Reply Last reply
          0
          • 0 Offline
            0 Offline
            010110102
            wrote on last edited by
            #5

            I solved the Problem.
            You can simply take the "myqsortfiltermodel" example and alter it to your needs.
            I will alter it in a way to make it dynamic... should I post it lateron?

            1 Reply Last reply
            0
            • M Offline
              M Offline
              ManasQt
              wrote on last edited by
              #6

              Hi Mr. 010110102,
              can you please post your solution? I am also on the same path.

              Thanks

              1 Reply Last reply
              0
              • 0 Offline
                0 Offline
                010110102
                wrote on last edited by
                #7

                Will do, cant do it right now and I have to alter it a bit, but in atleast 1-2 days.

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  ManasQt
                  wrote on last edited by
                  #8

                  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.

                  1 Reply Last reply
                  0
                  • 0 Offline
                    0 Offline
                    010110102
                    wrote on last edited by
                    #9

                    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_OBJECT

                    public:

                    //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 nessecary

                    protected:
                    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!

                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved