QSortFilterProxyModel 过滤进度查询:如何获取实时过滤行数实现进度可视化
QSortFilterProxyModel 过滤进度可视化实现方案
核心原理
原生 QSortFilterProxyModel 的过滤逻辑是内部黑盒执行,没有对外暴露处理进度回调,所以需要通过自定义子类重写过滤执行逻辑,插入进度上报的钩子来实现需求。
具体实现步骤
- 自定义继承
QSortFilterProxyModel的代理类,新增进度相关的信号和控制字段
头文件核心定义示例:class ProgressSortFilterProxy : public QSortFilterProxyModel { Q_OBJECT signals: // 进度变化信号:当前已处理行数,总行数 void filterProgressChanged(int processed, int total); // 过滤完成信号 void filterFinished(); private: // 过滤中断标记,可选用于支持用户取消过滤 bool m_abortFilter = false; // 计数步长,避免频繁发射信号卡UI const int m_progressStep = 50; protected: // 重写过滤触发逻辑 void invalidateFilter() override; }; - 重写
invalidateFilter方法,插入进度统计逻辑
实现时遍历源模型所有行,逐行调用原生filterAcceptsRow方法判断是否保留,每处理完固定步长的行数就发射一次进度信号:void ProgressSortFilterProxy::invalidateFilter() { m_abortFilter = false; int totalRows = sourceModel()->rowCount(); int processed = 0; beginResetModel(); // 清空原有过滤结果的逻辑可根据需要自行补充 for (int i = 0; i < totalRows; i++) { if (m_abortFilter) break; // 调用原生过滤判断逻辑,不破坏原有规则 filterAcceptsRow(i, QModelIndex()); processed++; // 达到步长时发射进度信号 if (processed % m_progressStep == 0 || processed == totalRows) { emit filterProgressChanged(processed, totalRows); } } endResetModel(); emit filterFinished(); } - UI 层绑定进度条
将自定义代理类的filterProgressChanged信号绑定到 QProgressBar 的setValue槽,过滤触发前将进度条最大值设置为源模型总行数,收到filterFinished信号后重置/隐藏进度条即可。
注意事项
大数量级场景下建议将遍历过滤逻辑放到后台线程执行,避免进度条和主UI卡顿
步长m_progressStep可以根据总行数动态调整,总行数越大步长可设置越高,减少信号发射频率
如果需要支持用户中途取消过滤,对外暴露修改m_abortFilter标记的接口即可
内容的提问来源于stack exchange,提问作者Dima Velevas
相关产品推荐
相关产品推荐

