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
QtWS25 Last Chance

QSortFilterProxyModel OR connection

Scheduled Pinned Locked Moved General and Desktop
9 Posts 3 Posters 3.8k Views
  • 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