本例中重要包含qtablevie,MyModel(QAbstractTableModel的子类),mysortmodel(QSortFilterProxyModel)的子类。
触发排序的途径主要由一下几种:
1.点击QTableView的表头触发排序。
2.直接调用QTableView的函数进行排序:
void QTableView::sortByColumn(int column, Qt::SortOrder order)
3.调用QSortFiterProxyModel的函数进行排序:
virtual void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override
下面先从第一种方式说起:
1.点击QTableView的表头触发排序
点击表头的调用栈如下图所示:
点击表头之后的鼠标事件处理过程略,触发排序的过程主要是:
void QHeaderView::setSortIndicator(int logicalIndex, Qt::SortOrder order)
{
。。。。。。
emit sortIndicatorChanged(logicalIndex, order);
}
然后触发QTableView的Slot:
void QTableView::sortByColumn(int column)
{
Q_D(QTableView);
if (column == -1)
return;
d->model->sort(column, d->horizontalHeader->sortIndicatorOrder());
}
此函数中检查一下列是否未-1就直接调用model的sort函数,由于我们这里使用了代理类,因此就调用了代理类(QSortFiterProxyModel)的sort函数,下边我们看看代理类中的sort函数时怎么处理的。
void QSortFilterProxyModel::sort(int column, Qt::SortOrder order)
{
Q_D(QSortFilterProxyModel);
if (d->dynamic_sortfilter && d->proxy_sort_column == column && d->sort_order == order)
return;
d->sort_order = order;
d->proxy_sort_column = column;
d->update_source_sort_column();
d->sort();
}
代理类中首先检查当前排序的行和排序方式(升序降序)是否跟上一次时一样的,如果时一样的就返回。
如果不一样,则保存这次排序的排序方式和行。
然后调用两个函数update_source_sort_column 和sort函数。
update_source_sort_column 这个函数比较复杂,主要是把数据model(此例中是MyModel)中行和列和代理Model(MySortModel)的行和列对应起来。因为使用代理类排序之后是不会改变数据model中的数据顺序的。
class QSortFilterProxyModelPrivate : public QAbstractProxyModelPrivate
{
Q_DECLARE_PUBLIC(QSortFilterProxyModel)
public:
struct Mapping {