Important: Please read the Qt Code of Conduct -

[solved]Problem with QSortFilterProxyModel and calculated field.

  • I have an QSqlQueryModel feeding a QSortFilterProxyModel derived class which filters the data, including calculating the proper value one column if it finds a flag value of -1. This displays on a QTableView as expected.

    The problem I'm having happens when I insert another QSortFilterProxyModel derived class between my filter and QTableView to sort this data. It sorts all the columns properly except for the semi-calculated field. The data that was originally not the flag value seems to sort fine but the calculated values do not. It's as if my sorting class reaches back to the original model for its data rather than taking it from the output of the filter model.

    Here's a visual of my setup...

    QSqlQueryModel --> QSortFilterProxyModel (subclassed to filter/calculate) --> QSortFilterProxyModel (subclassed to sort) --> QTableView.

    The filter reimplements (filterAcceptsRow) for filtering and (data) for the calculated field. Here is the (data) code. WORKDAYS is the semi-calculated field.

    [solved] looking over my code, I noticed my mistake.
    I needed Qt::DisplayRole instead of role when fetching rcvd.
    Sorry for the noise.

    QVariant FilterProxyModel::data(const QModelIndex &index, int role) const
        bool ok;
        int col= index.column();
        QVariant val= QSortFilterProxyModel::data(index, Qt::DisplayRole);
        QVariant rv= QSortFilterProxyModel::data(index, role);  // default return value
        int workdays= val.toInt(&ok);
        switch (col)
        case ISSUED:
        case RECD:
        case DONE:
        case SHIPPED:       // date columns
            QDate date= val.toDate();
            if (role == Qt::UserRole)   // for sorting
                return QVariant(date.toString("yyyy.MM.dd"));
            else if (role == Qt::DisplayRole)
                return QVariant(date.toString("dd MMM yyyy"));
        case WORKDAYS:
            if (workdays == -1 && ok)
                QModelIndex rcdIx= index.sibling(index.row(), RECD);
                QDate rcvd= QSortFilterProxyModel::data(rcdIx,***s/role/Qt::DisplayRole/***).toDate();  // received date
                if (rcvd.isValid())
                    workdays= workDays(rcvd, QDate::currentDate());
                    workdays= 0;
            if (role == Qt::UserRole || role == Qt::DisplayRole)
                return QVariant(workdays);
            if (role == Qt::UserRole || role == Qt::DisplayRole)
                return QVariant(val.toString());
        return rv;

Log in to reply