c++qtqsortfilterproxymodel

How to make QSortFilterProxyModel stop showing incomplete matches in search results?


I'm writing a database management application project for an animal shelter in which I use QSortFilterProxyModel to show search results. The problem is that the proxy model search shows even incomplete matches. For example if I have three animals with the ids 35, 388 and 3 and I search for an animal with id 3, it shows me all 3 of them because their ids all contain 3.

Here some of my code:

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
    ui->setupUi(this);

    proxyModel1 = new QSortFilterProxyModel(this);
    proxyModel1->setSourceModel(&model);
    ...
    connect(idEdit, SIGNAL(textChanged(const QString&)), this, SLOT(searchChanged()));
}

void MainWindow::searchChanged() {

    proxyModel1->setFilterRegExp(QRegExp(idEdit->text(), Qt::CaseInsensitive));
    proxyModel1->setFilterKeyColumn(0);
}

I need to stop that from happening.


Solution

  • The method that serves to filter an exact string does not exist so it must be implemented override the filterAcceptsRow() method:

    class SortFilterProxyModel: public QSortFilterProxyModel
    {
    public:
        using QSortFilterProxyModel::QSortFilterProxyModel;
        QString fixedString() const{
            return m_fixedString;
        }
    
        void setFixedString(const QString &fixedString){
            if(m_fixedString == fixedString) return;
            m_fixedString = fixedString;
            invalidateFilter();
        }
    
    protected:
        bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override{
            if(m_fixedString.isEmpty())
                return true;
            QModelIndex ix = sourceModel()->index(source_row, filterKeyColumn(), source_parent);
            return ix.data().toString() == m_fixedString;
        }
    private:
        QString m_fixedString;
    };
    
    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
        ui->setupUi(this);
    
        proxyModel1 = new SortFilterProxyModel(this);
        proxyModel1->setSourceModel(&model);
        connect(idEdit, &QLineEdit::textChanged, this, &MainWindow::searchChanged);    
    }
    
    void MainWindow::searchChanged() {
        proxyModel1->setFixedString(idEdit->text());
        proxyModel1->setFilterKeyColumn(0);
    }