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 strange behavior with QRegExp
Forum Updated to NodeBB v4.3 + New Features

QSortFilterProxyModel strange behavior with QRegExp

Scheduled Pinned Locked Moved Solved General and Desktop
22 Posts 3 Posters 1.9k 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.
  • ? Offline
    ? Offline
    A Former User
    wrote on last edited by A Former User
    #9

    I say (guess) at the filter proxy.

    Let me try to explain it again. I have a QLineEdit that has the name "searchbar". When I type something in it, it should search the data from mFungusModel. For this I thought I use the QSortFilterProxyModel() (in my case it is called mFungusProxyModel)

    I created a slot "textChanged(QString)" which in my case is called "on_searchbar_textChanged(const QString &name)". The code for this slot looks like this:

    void MainWindow::on_searchbar_textChanged(const QString &name)
    {
        QRegularExpression regExp;
        regExp.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
    
        ui->selection->setCurrentIndex(0);
        if(ui->selection->currentIndex() == 0)
        {
            mFungusProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
            mFungusProxyModel->setFilterKeyColumn(1);
            if(name.contains(QRegExp("\\s")))
            {
                QStringList word = name.split(QRegExp("\\s"));
                regExp.setPattern("^" + QRegExp::escape(word[0]) + "\\w*\\s" + QRegExp::escape(word[1]) + "\\w*");
            }
            else
            {
                regExp.setPattern("^" + QRegExp::escape(name) + "\\w*");;
            }
            mFungusProxyModel->setFilterRegExp(regExp.pattern());
            ui->listView->setModel(mFungusProxyModel);
            ui->listView->setModelColumn(1);
        }
    }
    

    Now when I type "bol" into my search bar then my QListView (in my case it's just called listview) doesn't show me. But if I type "bol" with a space, i.e. "bol " then it shows me the desired results.

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #10

      Please show the exact pattern you have.

      Note that you should really use the proper overloads. The configuration you set on QRegExp or QRegularExpression like case sensitivity is not something that is translatable through the pattern itself.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • ? Offline
        ? Offline
        A Former User
        wrote on last edited by
        #11

        My pattern looks like this:

        [...]
                if(name.contains(QRegExp("\\s")))
                {
                    QStringList word = name.split(QRegExp("\\s"));
                    regExp.setPattern("^" + QRegExp::escape(word[0]) + "\\w*\\s" + QRegExp::escape(word[1]) + "\\w*");
                }
                else
                {
                    regExp.setPattern("^" + QRegExp::escape(name) + "\\w*");;
                }
        [...]
        

        The debugger shows following, if I type:
        bol -> ^bol\w*
        bol whit space like "bol " -> ^bol\w*\s\w*
        bol edu -> ^bol\w*\sedu\w*

        @SGaist said in QSortFilterProxyModel strange behavior with QRegExp:

        Note that you should really use the proper overloads.

        Sorry I don't know what you mean. Please make an example for my code.

        JonBJ 1 Reply Last reply
        0
        • ? A Former User

          My pattern looks like this:

          [...]
                  if(name.contains(QRegExp("\\s")))
                  {
                      QStringList word = name.split(QRegExp("\\s"));
                      regExp.setPattern("^" + QRegExp::escape(word[0]) + "\\w*\\s" + QRegExp::escape(word[1]) + "\\w*");
                  }
                  else
                  {
                      regExp.setPattern("^" + QRegExp::escape(name) + "\\w*");;
                  }
          [...]
          

          The debugger shows following, if I type:
          bol -> ^bol\w*
          bol whit space like "bol " -> ^bol\w*\s\w*
          bol edu -> ^bol\w*\sedu\w*

          @SGaist said in QSortFilterProxyModel strange behavior with QRegExp:

          Note that you should really use the proper overloads.

          Sorry I don't know what you mean. Please make an example for my code.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #12

          @Gabber
          I don't claim to know what is going on. And if you say

          If I then delete " edu" again, so that I only have "bol" again, everything that starts with "bol" also appears. Only if I enter "bol" to start the program, the search does not work.

          that sounds odd, because you are claiming you end up with the same reg exp as you started with but different behaviour. Which sounds like a QSortFilterProxyModel rather than a reg exp thing.

          Just a couple of suggestions:

          • Try using \S in place of \w. Any difference?

          • Try using ., or even (.|\n), in place of \w. Any difference?

          • You are going to move over from QRegExp to QRegularExpression, aren't you? Do so now. If by any chance it's a QRegExp issue with QSortFilterProxyModel which works with QRegularExpression, it's not worth the effort to deal with.

          1 Reply Last reply
          0
          • ? Offline
            ? Offline
            A Former User
            wrote on last edited by
            #13

            @JonB said in QSortFilterProxyModel strange behavior with QRegExp:

            Try using \S in place of \w. Any difference?

            No difference.

            @JonB said in QSortFilterProxyModel strange behavior with QRegExp:

            Try using ., or even (.|\n), in place of \w. Any difference?

            No difference.

            @JonB said in QSortFilterProxyModel strange behavior with QRegExp:

            You are going to move over from QRegExp to QRegularExpression, aren't you?

            I switched to QRegularExrpession. Now my code looks like this:

            void MainWindow::on_searchbar_textChanged(const QString &name)
            {
                QRegularExpression regularExpression;
                regularExpression.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
            
                ui->selection->setCurrentIndex(0);
                if(ui->selection->currentIndex() == 0)
                {
                    mFungusProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
                    mFungusProxyModel->setFilterKeyColumn(1);
                    if(name.contains(QRegularExpression("\\s")))
                    {
                        QStringList word = name.split(QRegularExpression("\\s"));
                        regularExpression.setPattern("^" + QRegularExpression::escape(word[0]) + "\\w*\\s" + QRegularExpression::escape(word[1]) + "\\w*");
                    }
                    else
                    {
                        regularExpression.setPattern("^" + QRegularExpression::escape(name) + "\\w*");
                    }
                    mFungusProxyModel->setFilterRegularExpression(regularExpression);
                    ui->listView->setModelColumn(1);
                    ui->listView->setModel(mFungusProxyModel);
                }
            }
            

            Here's what else I found out: If I enter "bole" instead of "bol" then the search starts and lists all names that start with "bole".

            I suspect it is the QSortFilterProxyModel. Can I somehow say there I want to search for 3 letters? Unfortunately I didn't find anything in the documentation.

            Do you have any other idea how I can implement this differently?

            JonBJ 1 Reply Last reply
            0
            • ? A Former User

              @JonB said in QSortFilterProxyModel strange behavior with QRegExp:

              Try using \S in place of \w. Any difference?

              No difference.

              @JonB said in QSortFilterProxyModel strange behavior with QRegExp:

              Try using ., or even (.|\n), in place of \w. Any difference?

              No difference.

              @JonB said in QSortFilterProxyModel strange behavior with QRegExp:

              You are going to move over from QRegExp to QRegularExpression, aren't you?

              I switched to QRegularExrpession. Now my code looks like this:

              void MainWindow::on_searchbar_textChanged(const QString &name)
              {
                  QRegularExpression regularExpression;
                  regularExpression.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
              
                  ui->selection->setCurrentIndex(0);
                  if(ui->selection->currentIndex() == 0)
                  {
                      mFungusProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
                      mFungusProxyModel->setFilterKeyColumn(1);
                      if(name.contains(QRegularExpression("\\s")))
                      {
                          QStringList word = name.split(QRegularExpression("\\s"));
                          regularExpression.setPattern("^" + QRegularExpression::escape(word[0]) + "\\w*\\s" + QRegularExpression::escape(word[1]) + "\\w*");
                      }
                      else
                      {
                          regularExpression.setPattern("^" + QRegularExpression::escape(name) + "\\w*");
                      }
                      mFungusProxyModel->setFilterRegularExpression(regularExpression);
                      ui->listView->setModelColumn(1);
                      ui->listView->setModel(mFungusProxyModel);
                  }
              }
              

              Here's what else I found out: If I enter "bole" instead of "bol" then the search starts and lists all names that start with "bole".

              I suspect it is the QSortFilterProxyModel. Can I somehow say there I want to search for 3 letters? Unfortunately I didn't find anything in the documentation.

              Do you have any other idea how I can implement this differently?

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #14

              @Gabber
              Using the regular expression filter in QSortFilterProxyModel is only a "convenience" for you, you don't have to use it. You can subclass and and implement your own code for virtual protected bool QSortFilterProxyModel::filterAcceptsRow() if you cannot get the regular expression to work right for some reason.

              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #15

                The length of the expression should have no importance as long it's properly written.

                Can you write a minimal compilable example that uses a QStandardItemModel with some suitable entries and your proxy setup so that we can test it ?

                Note that you can also to some testing with the QRegularExpression tool from Qt's examples.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                ? 1 Reply Last reply
                0
                • SGaistS SGaist

                  The length of the expression should have no importance as long it's properly written.

                  Can you write a minimal compilable example that uses a QStandardItemModel with some suitable entries and your proxy setup so that we can test it ?

                  Note that you can also to some testing with the QRegularExpression tool from Qt's examples.

                  ? Offline
                  ? Offline
                  A Former User
                  wrote on last edited by
                  #16

                  @SGaist
                  I have made a very simple example that corresponds to what I want to search. If I take the QStandardItemModel my QRegularExpression also works as expected with QSortFilterProxyModel. Here is my code.

                  main.cpp

                  #include "mainwindow.h"
                  
                  #include <QApplication>
                  
                  int main(int argc, char *argv[])
                  {
                      QApplication a(argc, argv);
                      MainWindow w;
                      w.show();
                      return a.exec();
                  }
                  

                  mainwindow.cpp

                  #include "mainwindow.h"
                  #include "ui_mainwindow.h"
                  
                  MainWindow::MainWindow(QWidget *parent)
                      : QMainWindow(parent)
                      , ui(new Ui::MainWindow)
                  {
                      ui->setupUi(this);
                      ui->comboBox->addItem("Vollnamen");
                      ui->comboBox->setCurrentText("Vollnamen");
                      QStringList fungusList{
                          "Boletus aereus Bulliard ex Fr.",
                          "Boletus betulicola (Vassilkov) Pilat & Dermek",
                          "Boletus carpinaceus Velen.",
                          "Boletus edulis Bulliard",
                          "Boletus edulis var.arenarius Engel, Krglst. & Dermek",
                          "Boletus edulis var.clavipes Peck",
                          "Abortiporus biennis (Bull.) Singer",
                          "Adustomyces spec.",
                          "Euryachora spec",
                          "Diaporthe strumella (Fries) Fuckel",
                          "Cudonia spec."
                      };
                  
                      mFungusListModel = new QStandardItemModel(fungusList.count(),0);
                      for(int row=0; row<mFungusListModel->rowCount(); row++){
                          QStandardItem *item = new QStandardItem(QString(fungusList.at(row)));
                          mFungusListModel->setItem(row,0,item);
                      }
                  
                  
                      mFungusProxyModel = new QSortFilterProxyModel();
                      mFungusListModel->sort(0);
                      mFungusProxyModel->setSourceModel(mFungusListModel);
                      ui->listView->setModel(mFungusProxyModel);
                      ui->listView->setModelColumn(0);
                  
                  }
                  
                  MainWindow::~MainWindow()
                  {
                      delete ui;
                  }
                  
                  
                  void MainWindow::on_lineEdit_textChanged(const QString &name)
                  {
                      QRegularExpression regularExpression;
                      regularExpression.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
                  
                      ui->comboBox->setCurrentIndex(0);
                      if(ui->comboBox->currentIndex() == 0)
                      {
                          mFungusProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
                          mFungusProxyModel->setFilterKeyColumn(0);
                          if(name.contains(QRegularExpression("\\s")))
                          {
                              QStringList word = name.split(QRegularExpression("\\s"));
                              regularExpression.setPattern("^" + QRegularExpression::escape(word[0]) + "\\w*\\s" + QRegularExpression::escape(word[1]) + "\\w*");
                          }
                          else
                          {
                              regularExpression.setPattern("^" + QRegularExpression::escape(name) + "\\w*");
                          }
                          mFungusProxyModel->setFilterRegularExpression(regularExpression);
                          ui->listView->setModelColumn(0);
                          ui->listView->setModel(mFungusProxyModel);
                      }
                  }
                  

                  mainwindow.h

                  #ifndef MAINWINDOW_H
                  #define MAINWINDOW_H
                  
                  #include <QMainWindow>
                  #include <QSortFilterProxyModel>
                  #include <QStandardItemModel>
                  
                  QT_BEGIN_NAMESPACE
                  namespace Ui { class MainWindow; }
                  QT_END_NAMESPACE
                  
                  class MainWindow : public QMainWindow
                  {
                      Q_OBJECT
                  
                  public:
                      MainWindow(QWidget *parent = nullptr);
                      ~MainWindow();
                  
                  private slots:
                      void on_lineEdit_textChanged(const QString &name);
                  
                  private:
                      Ui::MainWindow *ui;
                      QSortFilterProxyModel *mFungusProxyModel;
                      QStandardItemModel *mFungusListModel;
                  };
                  #endif // MAINWINDOW_H
                  
                  

                  mainwindow.ui

                  <?xml version="1.0" encoding="UTF-8"?>
                  <ui version="4.0">
                   <class>MainWindow</class>
                   <widget class="QMainWindow" name="MainWindow">
                    <property name="geometry">
                     <rect>
                      <x>0</x>
                      <y>0</y>
                      <width>424</width>
                      <height>590</height>
                     </rect>
                    </property>
                    <property name="windowTitle">
                     <string>MainWindow</string>
                    </property>
                    <widget class="QWidget" name="centralwidget">
                     <layout class="QVBoxLayout" name="verticalLayout">
                      <item>
                       <widget class="QLineEdit" name="lineEdit"/>
                      </item>
                      <item>
                       <widget class="QComboBox" name="comboBox"/>
                      </item>
                      <item>
                       <widget class="QListView" name="listView"/>
                      </item>
                     </layout>
                    </widget>
                    <widget class="QMenuBar" name="menubar">
                     <property name="geometry">
                      <rect>
                       <x>0</x>
                       <y>0</y>
                       <width>424</width>
                       <height>23</height>
                      </rect>
                     </property>
                    </widget>
                    <widget class="QStatusBar" name="statusbar"/>
                   </widget>
                   <resources/>
                   <connections/>
                  </ui>
                  
                  

                  What could be the problem now? Do you have another idea? Do you need any code to analyze the problem? I hope we can work this out somehow. The search function is the most important thing in the program.

                  Thanks already :)

                  1 Reply Last reply
                  0
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #17

                    @Gabber said in QSortFilterProxyModel strange behavior with QRegExp:

                    If I take the QStandardItemModel my QRegularExpression also works as expected with QSortFilterProxyModel.

                    Do you mean that with the QStandardItemModel the erroneous behaviour does not trigger ?

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    ? 1 Reply Last reply
                    0
                    • SGaistS SGaist

                      @Gabber said in QSortFilterProxyModel strange behavior with QRegExp:

                      If I take the QStandardItemModel my QRegularExpression also works as expected with QSortFilterProxyModel.

                      Do you mean that with the QStandardItemModel the erroneous behaviour does not trigger ?

                      ? Offline
                      ? Offline
                      A Former User
                      wrote on last edited by
                      #18

                      @SGaist said in QSortFilterProxyModel strange behavior with QRegExp:

                      Do you mean that with the QStandardItemModel the erroneous behaviour does not trigger ?

                      Yes, that's what I mean. My search works exactly as I imagine it.

                      1 Reply Last reply
                      0
                      • SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #19

                        In that case, the problem might be with mFungusModel.

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        ? 1 Reply Last reply
                        0
                        • SGaistS SGaist

                          In that case, the problem might be with mFungusModel.

                          ? Offline
                          ? Offline
                          A Former User
                          wrote on last edited by A Former User
                          #20

                          @SGaist
                          I have created a file DatabaseManager.cpp. The following function exists in it:

                          QSqlTableModel *DatabaseManager::fungusTable() const
                          {
                              QSqlTableModel *model = new QSqlTableModel();
                              model->setTable("Pilze");
                              model->setSort(1, Qt::AscendingOrder);
                              model->select();
                              return model;
                          }
                          

                          In my mainwindow.h I do this:

                          private:
                              Ui::MainWindow *ui;
                              DatabaseManager *mDatabaseManager;
                              SettingsManager *mSettingsManager;
                              QDataWidgetMapper *mFungusMapper;
                              QSqlTableModel *mFungusModel;
                          

                          And in my constructor in my mainwindow.cpp I assign the data from the DatabaseManager to mFungusModel.

                          [...]
                              if(isStandardDatabasePathSet)
                              {
                                  const QString standardDatabase = mSettingsManager->loadStandardDatabase();
                          
                                  mDatabaseManager->openDatabase(standardDatabase);
                          
                                  ui->selection->setCurrentText("Vollnamen");
                          
                                  mFungusMapper = new QDataWidgetMapper();
                                  mFungusProxyModel = new QSortFilterProxyModel();
                          
                                  mFungusModel = mDatabaseManager->fungusTable();
                          
                                  mFungusProxyModel->setSourceModel(mFungusModel);
                                  ui->listView->setModel(mFungusProxyModel);
                                  ui->listView->setModelColumn(1);
                              }
                          [...]
                          

                          That's all what I'm doing in my constructor of mainwindow.cpp

                          1 Reply Last reply
                          0
                          • ? Offline
                            ? Offline
                            A Former User
                            wrote on last edited by
                            #21

                            Can someone please give me a hint what I can do now?

                            Why does the search work when I type four characters or type three characters and delete one?

                            I have no idea what to look for to solve / address this problem.

                            Tips are gratefully accepted.

                            1 Reply Last reply
                            0
                            • ? Offline
                              ? Offline
                              A Former User
                              wrote on last edited by
                              #22

                              My problem was solved in this Thread:
                              https://forum.qt.io/topic/131616/does-qsqltablemodel-have-a-limit-of-records

                              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