Important: Please read the Qt Code of Conduct -

Can't get Icons in vertical header with QSortFilterProxyModel

  • Hello,

    I'm working on a program that reads in a text file and puts data into a QStandardItemModel attached to a QTableView. If a particular word appears in a line of text read from the file, the program will put an "X" icon in the vertical header for that particular row. I'm having a problem with this X appearing in a QSortFilterProxyModel.

    Everything works fine in standard form. However, I'm implementing filtering capability on the tableview with a 2 QLineEdit input fields above the table. I connect the two lineEdits to a filterChanged() slot and I reimplemented QSortFilterProxyModel as follows:


    #include <QSortFilterProxyModel>

    class MySortFilterProxyModel : public QSortFilterProxyModel
    explicit MySortFilterProxyModel(QObject *parent = 0);
    QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const;

    bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
    #include "mysortfilterproxymodel.h"
    #include <QIcon>

    MySortFilterProxyModel::MtSortFilterProxyModel(QObject *parent) :
    bool MySortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
    QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent);
    QModelIndex index1 = sourceModel()->index(sourceRow, 1, sourceParent);
    //filtering on 2 columns

    QString filt1 = filterRegExp().pattern().section("|",0,0);
    QString filt2 = filterRegExp().pattern().section("|",1,1);
    QRegExp f1(filt1);
    QRegExp f2(filt2);
    return (sourceModel()->data(index0).toString().contains(f1)
                 && sourceModel()->data(index1).toString().contains(f2));


    QVariant MySortFilterProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
    if (orientation == Qt::Vertical){
    if (role == Qt::DecorationRole)
    return QIcon(":MyProgram/images/x.png");
    return QSortFilterProxyModel::headerData(section, orientation, role);
    return QSortFilterProxyModel::headerData(section, orientation, role);

    My filterChanged() slot:
    void MainWindow::filterChanged(const QString &filt)
    QString toFilt = filt;
    QString filt1, filt2= "";

    filt1 = ui->colOneFilterLineEdit->text();
    filt2 = ui->colTwoFilterLineEdit->text();
    toFilt = filt1 + "|" + filt2;


    Here is the model setup and the line of code that detects the particular word and then places the X in the vertical header:
    parseModel = new QStandardItemModel(0, 2, this);
    parseModel ->setHeaderData(0, Qt::Horizontal, "Direction");
    parseModel ->setHeaderData(1, Qt::Horizontal, "Street");

    //filtering proxy model for parsing table model
    proxyModel = new MySortFilterProxyModel;

    // ... Code to read in file line by line and parse each line into the model. If the "word" is found, set wordPresent to true ...

    if (wordPresent){

    The problem I'm having is that the line of code that checks for the particular word and then places an X in the vertical column works fine when there's no QSortFilterProxyModel. That is to say the X shows up fine in the vertical header. Once I attach the proxy model, the X goes away. So I did some Google searches and saw suggestions to implement QSortFilterProxyModel::headerData(), which I tried above. But this winds up placing an X on every single row as well as a row number, so I don't think I'm doing it properly. I also tried returning a QVariant() when no Vertical or DecorationRole was detected in the mysortfilterproxymodel, but that essentially erased the vertical header.

    Can anybody help me understand where I'm going wrong and provide a suggestion to right the ship??? Thanks so much!

Log in to reply