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 2.3k 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
    #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