QStandardItemModel 是标准的以项数据(item data)为基础的标准数据模型类,通常与 QTableView 组合成 Model/View 结构,实现通用的二维数据的管理功能。
对数据进行排序,可以列进行排序,我们看一下排序的过程实现。
QStandardItemModel 需要设置排序的的role,调用setSortRole进行设置,默认是Qt::DisplayRole.
1、如果是tableview ,可以设置setSortingEnabled ,会立即调用sortByColumn 进行排序。最终调用model的sort方法
void QTableView::setSortingEnabled(bool enable)
{
Q_D(QTableView);
d->sortingEnabled = enable;
horizontalHeader()->setSortIndicatorShown(enable);
if (enable) {
disconnect(d->horizontalHeader, SIGNAL(sectionEntered(int)),
this, SLOT(_q_selectColumn(int)));
disconnect(horizontalHeader(), SIGNAL(sectionPressed(int)),
this, SLOT(selectColumn(int)));
connect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
this, SLOT(sortByColumn(int)), Qt::UniqueConnection);
sortByColumn(horizontalHeader()->sortIndicatorSection(),
horizontalHeader()->sortIndicatorOrder());
} else {
connect(d->horizontalHeader, SIGNAL(sectionEntered(int)),
this, SLOT(_q_selectColumn(int)), Qt::UniqueConnection);
connect(horizontalHeader(), SIGNAL(sectionPressed(int)),
this, SLOT(selectColumn(int)), Qt::UniqueConnection);
disconnect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
this, SLOT(sortByColumn(int)));
}
}
void QTableView::sortByColumn(int column, Qt::SortOrder order)
{
Q_D(QTableView);
d->horizontalHeader->setSortIndicator(column, order);
sortByColumn(column);
}
void QTableView::sortByColumn(int column)
{
Q_D(QTableView);
if (column == -1)
return;
d->model->sort(column, d->horizontalHeader->sortIndicatorOrder());
}
2、QStandardItemModel::sort ,然后调用的是根索引进行排序。参数是需要排序的列,默认是正向排序。
void QStandardItemModel::sort(int column, Qt::SortOrder order)
{
Q_D(QStandardItemModel);
d->root->sortChildren(column, order);
}
void QStandardItem::sortChildren(int column, Qt::SortOrder order)
{
Q_D(QStandardItem);
if ((column < 0) || (rowCount() == 0))
return;
QList<QPersistentModelIndex> parents;
if (d->model) {
parents << index();
emit d->model->layoutAboutToBeChanged(parents, QAbstractItemModel::VerticalSortHint);
}
d->sortChildren(column, order);
if (d->model)
emit d->model->layoutChanged(parents, QAbstractItemModel::VerticalSortHint);
}
QStandardItemPrivate::sortChildren完成
void QStandardItemPrivate::sortChildren(int column, Qt::SortOrder order)
{
Q_Q(QStandardItem);
if (column >= columnCount())
return;
QVector<QPair<QStandardItem*, int> > sortable;
QVector<int> unsortable;
sortable.reserve(rowCount()); //预览空间rowCount()
unsortable.reserve(rowCount()); //
//遍历每一行,将获取到每一行中column列,获取到item放置到sortable
for (int row = 0; row < rowCount(); ++row) {
QStandardItem *itm = q->child(row, column);
if (itm)
sortable.append(QPair<QStandardItem*,int>(itm, row));
else
unsortable.append(row);
}
//按正向或者反向排序
if (order == Qt::AscendingOrder) {
QStandardItemModelLessThan lt;
std::stable_sort(sortable.begin(), sortable.end(), lt);
} else {
QStandardItemModelGreaterThan gt;
std::stable_sort(sortable.begin(), sortable.end(), gt);
}
//创建一个vector 遍历children
QModelIndexList changedPersistentIndexesFrom, changedPersistentIndexesTo;
QVector<QStandardItem*> sorted_children(children.count());
for (int i = 0; i < rowCount(); ++i) {
//前面先遍历已经有的节点
int r = (i < sortable.count()
? sortable.at(i).second
: unsortable.at(i - sortable.count()));
//遍历列
for (int c = 0; c < columnCount(); ++c) {
QStandardItem *itm = q->child(r, c);
sorted_children[childIndex(i, c)] = itm;
if (model) {
QModelIndex from = model->createIndex(r, c, q);
if (model->d_func()->persistent.indexes.contains(from)) {
QModelIndex to = model->createIndex(i, c, q);
changedPersistentIndexesFrom.append(from);
changedPersistentIndexesTo.append(to);
}
}
}
}
children = sorted_children;
if (model) {
model->changePersistentIndexList(changedPersistentIndexesFrom, changedPersistentIndexesTo);
}
//
QVector<QStandardItem*>::iterator it;
for (it = children.begin(); it != children.end(); ++it) {
if (*it)
(*it)->d_func()->sortChildren(column, order);
}
}