关键在于手动排序,需要决定是否按列-1(还原)或普通列号进行排序,并在某种程度上拦截
QHeaderView
和
QSortFilterProxyModel
之间的通信。
因此,借鉴了@vahancho答案中的一些见解,我已经成功实现了如下排序:
class ProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
ProxyModel(QObject* parent = 0);
signals:
void askOrder(int column, Qt::SortOrder order);
public slots:
void sort(int column, Qt::SortOrder order)
{
emit askOrder(column, order);
}
void doSort(int column, Qt::SortOrder order)
{
QSortFilterProxyModel::sort(column, order);
}
};
在父级的一侧,我进行了适当的连接和检查:
ResultsTable::ResultsTable(QWidget *parent) : QTableView(parent)
{
p_Header = new QHeaderView(this);
p_Sort = new ProxyModel(this);
connect(this, &ResultsTable::doSort, p_Sort, &ProxyModel::doSort);
connect(p_Sort, &ProxyModel::askOrder, this, &ResultsTable::setSorting);
setSortingEnabled(true);
}
void ResultsTable::setSorting(int column, Qt::SortOrder order)
{
if (p_Header->sortIndicatorOrder() == Qt::AscendingOrder && p_Header->isSortIndicatorShown() && m_PreviousSort == column)
{
p_Header->setSortIndicator(column, Qt::DescendingOrder);
p_Header->setSortIndicatorShown(false);
column = -1;
}
else
{
p_Header->setSortIndicatorShown(true);
}
m_PreviousSort = column;
emit doSort(column, order);
}
这样做可以利用
QTableView
自动排序,前提是
sortingEnabled
属性设置为
true
。我曾试图研究Qt中单击表头触发排序的内部处理过程,但未能成功,因此采用了这种方法。我仍然不确定这种方式是否正确,即
QTableView
负责设置正确的排序指示,而不是
QHeaderView
本身(我认为这个功能应该属于表头)。