QSortFilterProxyModel strange behavior with QRegExp
-
@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?
-
@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?
@Gabber
Using the regular expression filter inQSortFilterProxyModel
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. -
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.
-
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.
@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 :)
-
@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 ?
-
@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 ?
@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.
-
In that case, the problem might be with mFungusModel.
-
@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
-
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.
-
My problem was solved in this Thread:
https://forum.qt.io/topic/131616/does-qsqltablemodel-have-a-limit-of-records