Real-time filtering using QSortFilterProxyModel



  • I have a QTableView and a model. This is my filtering function:

    void filter( QString data ){
        pxModel->setFilterRegExp( data );
    }
    

    It searches only first column but I want to search all 5 of them. How can I do that?

    I found this post:
    http://www.qtcentre.org/threads/24267-QSortFilterProxyModel-setFilterRegExp-for-more-than-1-column?p=141791#post141791

    I've tried reimplementing filterAcceptsRow(...) function but I get error :"m_columnPatterns was not declared in this scope"

    Is there an easier way ?



  • Have you created a new class inheriting QSortFilterProxyModel?

    That's what I did and I can filter multiple column with this code:

    proxyModel->setSortCaseSensitivity(Qt::CaseSensitive);
    
    qDebug() << "filterChanged inside Workout Page!";
    qDebug() << field << "value" << value;
    
    if (field == "name") {
        proxyModel->addFilterFixedString(0, value);
    }
    else if (field == "plan") {
        proxyModel->addFilterFixedString(1, value);
    }
    else if (field == "creator") {
        proxyModel->addFilterFixedString(2, value);
    }
    else if (field == "workoutType") {
        proxyModel->addFilterFixedString(3, value);
    }
    /// Reset filter
    else {
        for (int i=0; i<4; i++) {
            proxyModel->addFilterFixedString(i, "");
        }
    }
    
    proxyModel->invalidate();
    
    
    
        void SortFilterProxyModel::addFilterFixedString(qint32 column, const QString &pattern)
        {
            if(!m_columnPatterns.contains(column)) {
                return;
            }
        
            m_columnPatterns[column] = pattern;
        
        }


  • I have a problem. Wehen i change text in my QLineEdit (text I want to search) everything gets removed from TableView.

    SortFilterProxyModel.h:

    #ifndef SORTFILTERPROXYMODEL_H
    #define SORTFILTERPROXYMODEL_H
    
    #include <QObject>
    #include <QSortFilterProxyModel>
    
    class SortFilterProxyModel : public QSortFilterProxyModel
    {
        Q_OBJECT
    public:
        explicit SortFilterProxyModel(QObject *parent = 0);
        ~SortFilterProxyModel();
        void setFilterKeyColumns(const QList<qint32> &filterColumns);
        void addFilterFixedString(qint32 column, const QString &pattern);
    
    protected:
        bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const;
    
    private:
        QMap<qint32, QString> m_columnPatterns;
    };
    
    #endif // SORTFILTERPROXYMODEL_H
    

    SortFilterProxyModel.cpp:

    #include "sortfilterproxymodel.h"
    
    SortFilterProxyModel::SortFilterProxyModel(QObject *parent) : QSortFilterProxyModel(parent)
    {
    }
    
    SortFilterProxyModel::~SortFilterProxyModel()
    {
    }
    
    void SortFilterProxyModel::setFilterKeyColumns(const QList<qint32> &filterColumns){
    m_columnPatterns.clear();
    
    foreach(qint32 column, filterColumns)
    m_columnPatterns.insert(column, QString());
    }
    
    void SortFilterProxyModel::addFilterFixedString(qint32 column, const QString &pattern){
    if(!m_columnPatterns.contains(column))
        return;
    
    m_columnPatterns[column] = pattern;
     }
    
    bool SortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex & source_parent) const{
    if(m_columnPatterns.isEmpty())
        return true;
    
    bool ret = false;
    
    for(QMap<qint32, QString>::const_iterator iter = m_columnPatterns.constBegin();
    iter != m_columnPatterns.constEnd();
    ++iter)
    {
        QModelIndex index = sourceModel()->index(source_row, iter.key(), source_parent);
        ret = (index.data().toString() == iter.value());
    
        if(!ret)
            return ret;
    }
    
    return ret;
    }
    

    In app constructor:

    model = new QSqlRelationalTableModel(this);
    proxyModel = new SortFilterProxyModel(this);
    proxyModel->setSourceModel(model);
    ui->tableView->setModel(proxyModel);
    
    // Adding columns to filter
    QList<qint32> lista;
    lista.append(0);
    lista.append(1);
    lista.append(2);
    lista.append(3);
    lista.append(4);
    proxyModel->setFilterKeyColumns(lista);
    
    // connecting the slot
    connect(ui->lineEdit, SIGNAL(textChanged(QString)), this, SLOT(search(QString)));
    

    I've created slot to handle the search:

    void search( QString data ){
        for (int i=0; i<4; i++){
            pxModel->addFilterFixedString(i, data);
            pxModel->invalidate();
        }
    }
    

    Why it doesn't work ?

    Whole project:
    https://www.dropbox.com/sh/p9rfwc8za439wi5/AADryEvjDeOn30SCykSoTRYea?dl=0


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.