20

I am using the QTableView to display a QAbstractTableModel:

#include <QtGui/QApplication>
#include <QAbstractTableModel>
#include <QTableView>

class TestModel : public QAbstractTableModel
{
public:
    int rowCount(const QModelIndex &parent = QModelIndex()) const
    {
        return 2;
    }
    int columnCount(const QModelIndex &parent = QModelIndex()) const
    {
        return 2;
    }
    QVariant data(const QModelIndex &index, int role) const
    {
        switch (role)
        {
        case Qt::DisplayRole:
        {
            return 4 - index.row() + index.column();
        }
        }
        return QVariant();
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QTableView table;
    TestModel model;
    table.setModel(&model);
    table.setSortingEnabled(true);
    table.sortByColumn(0, Qt::AscendingOrder);
    table.reset();
    table.show();

    return a.exec();
}

The displayed widget

The problem is that the result is exactly the same when I use:

table.sortByColumn(0, Qt::AscendingOrder);

or

table.sortByColumn(0, Qt::DescendingOrder);

or

table.sortByColumn(1, Qt::AscendingOrder);

or

table.sortByColumn(1, Qt::DescendingOrder);

What am I doing wrong?

sandwood
  • 2,038
  • 20
  • 38
Martin Drozdik
  • 12,742
  • 22
  • 81
  • 146

2 Answers2

26

QAbstractTableModel provides an empty sort() implementation.

Try doing

TestModel model;
QSortFilterProxyModel proxyModel;
proxyModel.setSourceModel( &model );
table.setModel( &proxyModel ); 
Tim Meyer
  • 12,210
  • 8
  • 64
  • 97
  • Thank you! It works! But what was I doing wrong? Why does my code not work?I have read the documentation of both QTableView and QAbstractTableModel up and down, but did not find out why. – Martin Drozdik Jul 23 '12 at 06:32
  • If I understand this correctly, the QTableView just calls the QAbstractTableModel's empty sort() function? It does not do any soting on its own? – Martin Drozdik Jul 23 '12 at 06:49
  • 1
    Yes exactly. QSqlTableModel does have a sort implementation iirc, so sorting works there without a proxy model. However, as you are using an own model, you need a QSortFilterProxyModel which - as the name suggests - does have a sorting implementation as well. – Tim Meyer Jul 23 '12 at 08:59
  • QTableView just forwards the sort call to model()->sort(...) – Tim Meyer Jul 23 '12 at 09:01
5

For those looking to do this in Python, this works for PySide6.

import sys
from PySide6.QtCore import QAbstractTableModel, Qt, QSortFilterProxyModel
from PySide6.QtWidgets import QTableView, QApplication

class TestModel(QAbstractTableModel):

    def __init__(self):
        super().__init__()

    def rowCount(self, index):
        return 2

    def columnCount(self, index):
        return 2

    def data(self, index, role):
        if role == Qt.DisplayRole:
            return 4 - index.row() + index.column()


def main():
    a = QApplication(sys.argv)

    table = QTableView()
    model = TestModel()
    proxyModel = QSortFilterProxyModel()
    proxyModel.setSourceModel(model)
    table.setModel(proxyModel)
    table.setSortingEnabled(True)
    table.sortByColumn(0, Qt.AscendingOrder)
    table.reset()
    table.show()

    sys.exit(a.exec())


if __name__ == "__main__":
    main()
Zachary Taylor
  • 153
  • 1
  • 11