Question

I create a qtableview with a custom model and a custom sortfilterproxymodel

IssueTableModel *issueModel = new IssueTableModel(this->_repository->getIssueList());
IssueTableSortFilterProxyModel *proxyModel = new IssueTableSortFilterProxyModel(this);
proxyModel->setSourceModel(issueModel);
this->_ui->issuesTable->setModel(proxyModel);

and in the sortfilterproxymodel constructor:

IssueTableSortFilterProxyModel::IssueTableSortFilterProxyModel(QObject *parent) : QSortFilterProxyModel(parent)
{
    this->setSortRole(Qt::UserRole);
    this->setFilterRole(Qt::UserRole);
}

with a custom lessThan method in the proxymodel. but when the data is retrieved via the model data method, only

  • Qt::DisplayRole
  • Qt::DecorationRole
  • Qt::FontRole
  • Qt::TextAlignmentRole
  • Qt::BackgroundRole
  • Qt::ForegroundRole
  • Qt::CheckStateRole
  • Qt::SizeHintRole

are called, but not Qt::UserRole which I need to output the correct sorting data for the model item:

QVariant IssueTableModel::data(const QModelIndex &index, int role) const
    switch (role) {
        case Qt::DecorationRole:
            // Display icons
            switch (index.column()) {
                [...]
            }
        case Qt::DisplayRole:
            // Display text data
            switch (index.column()) {
                [...]
            }
        case Qt::UserRole:
            qDebug() << "USER ROLE!!!!";
            // Return data for sorting/filtering
            switch (index.column()) {
                [...]
            }
        default:
            return QVariant();
    }
}

So the question is: Why does the data method of the model never get called with Qt::UserRole when sorting the proxymodel?

Solution:

I got the data in the lessThan method via:

bool IssueTableSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
{
    QVariant leftData = sourceModel()->data(left);
    QVariant rightData = sourceModel()->data(right);

    switch (leftData.type()) {
        case QVariant::Int:
            return leftData.toInt() < rightData.toInt();
        case QVariant::String:
            return leftData.toString() < rightData.toString();
        case QVariant::DateTime:
            return leftData.toDateTime() < rightData.toDateTime();
        default:
            return false;
    }
}

but did not set the second parameter of the data method which specifies the role...

QVariant leftData = sourceModel()->data(left, Qt::UserRole);
Was it helpful?

Solution

If you reimplement lessThan then you need to perform the sorting yourself. setSortRole only affects the default lessThan implementation.

OTHER TIPS

You should either:

call

void QSortFilterProxyModel::sort ( int column, Qt::SortOrder order = Qt::AscendingOrder ) [virtual]

setsorting in your view (and click columns)

setSortingEnabled(true); 

Set dynamic filtering

void QSortFilterProxyModel::setDynamicSortFilter ( bool enable )

Edit:

Note that, in docs. They say in example:

At this point, neither sorting nor filtering is enabled; the original data is displayed in the view. Any changes made through the QSortFilterProxyModel are applied to the original model.

You MUST fire the filtering/sorting

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top