如何在QSortFilterProxyModel列排序时排除最后一行不移动
解决方案:让手动输入行固定在排序后的表格底部
这个需求很常见,要实现这个效果,核心是重写QSortFilterProxyModel的lessThan()方法,自定义排序逻辑,让你的手动输入行始终“免疫”排序,固定在最后。下面是具体步骤和代码示例:
步骤1:自定义ProxyModel类
创建一个继承自QSortFilterProxyModel的子类,重写lessThan()方法来控制排序规则:
class FixedBottomRowProxyModel : public QSortFilterProxyModel { Q_OBJECT public: explicit FixedBottomRowProxyModel(QObject *parent = nullptr) : QSortFilterProxyModel(parent) {} protected: bool lessThan(const QModelIndex &left, const QModelIndex &right) const override { // 获取原始model的总行数,假设手动输入行是原始model的最后一行 int sourceRowCount = sourceModel()->rowCount(); // 检查左索引是否是原始model的最后一行 bool leftIsBottomRow = (left.row() == sourceRowCount - 1); // 检查右索引是否是原始model的最后一行 bool rightIsBottomRow = (right.row() == sourceRowCount - 1); // 如果其中一个是底部行,直接调整排序优先级 if (leftIsBottomRow) { // 左是底部行,让它排在后面,所以left不小于right,返回false return false; } if (rightIsBottomRow) { // 右是底部行,让它排在后面,所以left小于right,返回true return true; } // 其他行按照默认的排序逻辑处理(这里是Date列的默认排序) return QSortFilterProxyModel::lessThan(left, right); } };
步骤2:替换原ProxyModel
把你原来使用的QSortFilterProxyModel替换成这个自定义的FixedBottomRowProxyModel:
// 假设你的原始model是sourceModel,tableView是你的表格视图 FixedBottomRowProxyModel *proxyModel = new FixedBottomRowProxyModel(this); proxyModel->setSourceModel(sourceModel); tableView->setModel(proxyModel);
步骤3:正常调用排序
之后你依然可以用proxyModel->sort(2)来按Date列排序,此时手动输入行会始终保持在表格底部,不受排序影响。
额外说明
- 如果你的手动输入行不是原始model的最后一行,而是动态添加在ProxyModel里的,那需要额外处理
rowCount()和data()方法,同时在lessThan()里判断该行的标识(比如用一个特殊的data角色标记),逻辑类似,只要识别出该行就让它排在最后。 - 确保你的Date列数据格式是可正确比较的(比如用
QDate类型存储,而不是纯字符串),这样默认的lessThan()才能正确排序日期。
内容的提问来源于stack exchange,提问作者zloi_templar
相关产品推荐
相关产品推荐

