This will depend a little on the size of your dataset. Since we use a stable sort you can relatively easily achieve this by keeping a list of sort columns and sort them from last to first. See the example below for a demonstration.
If you have a lot of records you might want to implement your own model that will more efficiently sort based on multiple columns.
#include <QtGui>
#define SETPERSON(index, first, second, salary) setItem(index, 0, new QTableWidgetItem(first)); setItem(index, 1, new QTableWidgetItem(second)); setItem(index, 2, new QTableWidgetItem); item(index, 2)->setData(Qt::DisplayRole, salary);
class Table : public QTableWidget
{
Q_OBJECT
public:
Table(QWidget *parent = 0)
: QTableWidget(6, 3, parent)
{
SETPERSON(0, "Jerry", "Springer", 1000000);
SETPERSON(1, "Foo", "Springer", 12341);
SETPERSON(2, "John", "Wayne", 12341);
SETPERSON(3, "Bob", "Carver", 80000);
SETPERSON(4, "Bob", "Carver", 81000);
SETPERSON(5, "Bob", "Ulong", 60000);
updateSortOrder();
connect(horizontalHeader(), SIGNAL(sectionClicked(int)),
this, SLOT(onHeaderClicked(int)));
disconnect(horizontalHeader(), SIGNAL(sectionPressed(int)), this, SLOT(selectColumn(int)));
}
void updateSortOrder()
{
QStringList list;
list << "First name" << "Last name" << "Salary";
for (int i=0; i<sortOrder.size(); ++i)
list[sortOrder.at(i).column].append("(" + QString::number(i + 1) + ")");
setHorizontalHeaderLabels(list);
for (int i=sortOrder.size() - 1; i>=0; --i) {
sortItems(sortOrder.at(i).column, sortOrder.at(i).ascending ? Qt::AscendingOrder : Qt::DescendingOrder);
}
}
public slots:
void onHeaderClicked(int section)
{
bool ascending = true;
if (!(QApplication::keyboardModifiers() & Qt::ControlModifier) || sortOrder.isEmpty()) {
if (!sortOrder.isEmpty() && sortOrder.first().column == section) {
ascending = !sortOrder.first().ascending;
}
sortOrder.clear();
} else {
const int index = findSection(section);
if (index != -1) {
if (index == sortOrder.size() - 1) {
ascending = !sortOrder.last().ascending;
}
sortOrder.removeAt(index);
}
}
sortOrder.append(SortData(section, ascending));
updateSortOrder();
}
private:
int findSection(int section) const
{
for (int i=0; i<sortOrder.size(); ++i) {
if (sortOrder.at(i).column == section)
return i;
}
return -1;
}
struct SortData {
SortData(int sec = -1, bool asc = true) : column(sec), ascending(asc) {}
int column;
bool ascending;
};
QList<SortData> sortOrder;
};
#include "main.moc"
int main(int argc, char **argv)
{
QApplication a(argc, argv);
Table w;
w.show();
return a.exec();
}