1. QSortFilterProxyModel介绍

QSortFilterProxyModel类用来为model和view之间提供强大的排序和过滤支持。将模型排序或者过滤后在视图上显示,并且无需对模型中的数据进行任何转换,也无需对模型在中数据进行修改。

比如: 对某列筛选带有”xxx”的关键字出来.并支持多则表达式

使用代理的项视图模型代码如下:

QTreeView *treeView = new QTreeView;
MyItemModel *sourceModel = new MyItemModel(this);
QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this);
proxyModel->setSourceModel(sourceModel); //将model放入代理中
treeView->setModel(proxyModel); //在视图中安装代理

2.QSortFilterProxyModel自定义排序

自定义排序需要子类化QsortFilterProxyModel,然后重写lessThan().

注意 : 如果重写了lessThan(),那么就不会再调用model的sort方法了.

lessThan()使用示例:

bool SortFilterProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{//通过当前视图中的index位置获取model中实际的数据QVariant leftData = sourceModel()->data(source_left);QVariant rightData = sourceModel()->data(source_right);switch ( source_left.column() ){case 0 :     //序号,需要判断数字case 3 :     //信号ID,需要判断数字return leftData.toInt() < rightData.toInt();break;default :    //其它,只判断字符串return leftData.toString() < rightData.toString();break;}return true;     }

除了排序外,QSortFilterProxyModel还可以用来隐藏与某个过滤器不匹配的项。使用QRegExp对象指定筛选器,并将筛选器应用于给定列的每个项的filterRole() (默认情况下为Qt::DisplayRole)。QRegExp对象可用于匹配正则表达式、通配符模式或固定字符串。

  • QT正则表达式参考链接:59.QT-QRegExp和QRegularExpression

3.过滤方法1-使用setFilterKeyColumn()过滤列

首先需要通过void QSortFilterProxyModel::setFilterRegExp(const QRegExp &regExp)来设置FilterProxyModel的过滤器.

然后通过QSortFilterProxyModel::setFilterKeyColumn(int)来过滤某一列.

如果要更改大小写匹配,可以通过QSortFilterProxyModel::sortCaseSensitivity()来设置.

示例代码如下所示:

QTableView *view = new QTableView;
MyItemModel *sourceModel = new MyItemModel(this);
QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this);
proxyModel->setSourceModel(sourceModel); //将model放入代理中
view->setModel(proxyModel);             //在视图中安装代理QRegExp regExp("^(-?\\d+)(\\.\\d+)?$", Qt::CaseSensitive, QRegExp::RegExp);
//通过^(-?\d+)(\.\d+)?$来匹配整数
proxyModel->setFilterRegExp(regExp);   //安装过滤器proxyModel->setFilterKeyColumn(0);
proxyModel->setFilterKeyColumn(2);    //将第一列和第三列同时是整数的数据显示出来.

每当过滤格式改变,则setFilterRegExp()重新更新过滤器即可.

弊端:

  • 但是这样只能"与方式"显示model,要第一列和第三列公共是整数的才能显示出来,不能实现"或方式"显示.

所以,如果要使用联合多列过滤,建议使用过滤方法2来实现.

4.过滤方法2-重写filterAcceptsRow成员函数

以实现"只要第一列有整数或者第三列有整数的都显示出来"为例,首先需要子类化QSortFilterProxyModel类,然后重写filterAcceptsRow()或者filterAcceptsColumn()函数.

由于我们筛选第一列和第三列,列号是明确的,而行号是未知的, 所以我们只重写filterAcceptsRow()函数.

示例代码如下所示:

bool SortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{//获取model中实际的数据QString dataColumn1 =  sourceModel()->index(source_row, 0, source_parent).data(Qt::DisplayRole).toString();QString dataColumn3 =  sourceModel()->index(source_row, 2, source_parent).data(Qt::DisplayRole).toString();if(dataColumn1.contains(this->filterRegExp()))     {return true;}else if(dataColumn3.contains(this->filterRegExp())) {return true;}return false;        }

然后创建SortFilterProxyModel类时,只需要安装过滤器即可:

SortFilterProxyModel *proxyModel = new SortFilterProxyModel();
proxyModel->setSourceModel(sourceModel);            //将model放入代理中
treeView->setModel(proxyModel);                     //在视图中安装代理
proxyModel->setFilterRegExp("^(-?\\d+)(\\.\\d+)?$"); //安装过滤器

每当过滤格式改变,则setFilterRegExp()重新更新过滤器即可.

注意事项:

  • 如果过滤方式改变了,比如从过滤第1列变成了过滤第2列,需要调用invalidateFilter()函数,使之前的过滤失效,激活当前过滤.

5.代码示例

model采用上章代码的CustomModel为例.支持筛选多列、筛选模式支持:或方式、与方式、

界面实现如下所示:

下载链接:https://download.csdn.net/download/qq_37997682/13709981

sortfilterproxymodel.h如下所示:

#ifndef SORTFILTERPROXYMODEL_H
#define SORTFILTERPROXYMODEL_H#include <QObject>
#include <QSortFilterProxyModel>
#include <QList>class SortFilterProxyModel : public QSortFilterProxyModel
{Q_OBJECTvirtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;virtual bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;bool m_isOr;QList<int> m_selectdList;public:explicit SortFilterProxyModel(QSortFilterProxyModel *parent = nullptr);void ChangeFilterMode(bool isOr);        void ChangeFilterColumn( QList<int> selectdList);         signals:};#endif // SORTFILTERPROXYMODEL_H

sortfilterproxymodel.cpp如下所示:

#include "sortfilterproxymodel.h"
#include <QDebug>
SortFilterProxyModel::SortFilterProxyModel(QSortFilterProxyModel *parent): QSortFilterProxyModel(parent)
{}void SortFilterProxyModel::ChangeFilterMode(bool isOr)
{m_isOr = isOr;invalidateFilter();
}
void SortFilterProxyModel::ChangeFilterColumn( QList<int> selectdList)
{m_selectdList = selectdList;invalidateFilter();
}bool SortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{if(m_selectdList.isEmpty())return true;foreach(int column, m_selectdList) {QString data =  sourceModel()->index(source_row, column, source_parent).data(Qt::DisplayRole).toString();bool mathd = this->filterRegularExpression().match(data).hasMatch();if(m_isOr && mathd) {    return true;} else if(!m_isOr && !mathd) {     return false;}}if(m_isOr)          return false;elsereturn true;
}bool SortFilterProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{//通过当前视图中的index位置获取model中实际的数据QVariant leftData = sourceModel()->data(source_left);QVariant rightData = sourceModel()->data(source_right);switch ( source_left.column() ){case 0 :  case 3 :   return leftData.toInt() < rightData.toInt();break;default :    return leftData.toString() < rightData.toString();break;}return true;}

QSortFilterProxyModel实现排序、过滤相关推荐

  1. jpa 分页 排序 过滤_使用JPA标准@ViewScoped通过分页,过滤和排序进行Primefaces DataTable延迟加载...

    jpa 分页 排序 过滤 Primefaces数据表惰性分页有效,但是在Web上使用Criteria搜索完整示例后,我感到非常沮丧. 所以我混合了来自 http://stackoverflow.com ...

  2. MySQL 学习笔记(1)— 创建/连接/选择/显示数据库(表) 查询单列(多列/所有列)/查询返回特定的行数 各种排序(单列/多列/降序/组合排序) 过滤数据

    本文是对之前学习 MySQL 的一个总结,使用思维导图的方式将涉及到的知识点罗列出来,一方面作为自己对于知识点的归纳,另一方面也便于日后查询. 在该篇文章中将对 MySQL 的基本使用.检索基本数据. ...

  3. 用ASP.NET Core 2.1 建立规范的 REST API -- 翻页/排序/过滤等

    本文所需的一些预备知识可以看这里:  用ASP.NET Core 2.0 建立规范的 REST API -- 预备知识 和  用ASP.NET Core 2.0 建立规范的 REST API -- 预 ...

  4. mysql 排序 过滤_【MYSQL】-3 排序与过滤

    上周加入数据蛙二期培训,结束了孤独战斗的现状.断断续续自学了3个月(当然看了各种视频和各种书,一把辛酸泪...),现在选择报班,主要还是觉得一个靠谱的组织和团队,可以极大缓解我学习过程中不时闪现的焦虑 ...

  5. Vue 数组更新与排序过滤

    前面的话 Vue 的核心是数据与视图的双向绑定,当我们修改数组时,Vue会检测到数据变化,所以用v-for 渲染的视图也会立即更新.Vue为了增加列表渲染的功能,增加了一组观察数组的方法,而且可以显示 ...

  6. java stream 8 常用的操作集合 求和 排序 过滤 拿出对象元素组成集合

    举个例子拿一个教师给学生开家长会Java实体 解释 stream 流操作集合建立在内存之上非常的快 以下列举 常用的操作方法 @Data public class OpenClass {private ...

  7. oracle 分组过滤空值,oracle 空值处理,排序过滤

    oracle认为 null 最大. 升序排列,默认情况下,null值排后面. 降序排序,默认情况下,null值排前面. 有几种办法改变这种情况: (1)用 nvl 函数或decode 函数 将null ...

  8. SQL 对结果集进行分组排序过滤重复数据 ROW_NUMBER

    简单的表操作: select row_number() over(partition by A.gid order by A.gid ) as RowN, A.* from Fit_Order A 关 ...

  9. asp.net core 排序过滤分页组件:sieve(2)表达式树的复习

    在Sieve组件中使用了很多关于表达式树的知识,但在我们日常的工作中写表达式树的机会是非常少的,至少在我的编程生涯中没怎么写过表达式树(可能也就是3,4次).所以,为了能够看懂Sieve里面的源代码, ...

最新文章

  1. TCP/IP 协议簇 端口 三次握手 四次挥手 11种状态集
  2. WCF RIA Service实体类中发复杂类型
  3. linux——sshd服务及其管理命令
  4. 【渝粤教育】国家开放大学2018年秋季 2238T个案工作 参考试题
  5. [LeetCode] Z字型变换
  6. 华为方舟编译器正式开源,采用自主平台托管
  7. vue-json-excel前端导出excel教程
  8. Matlab中图像函数大全
  9. One Switch for Mac(系统功能快速切换工具)
  10. 利用pytesseract图像识别文字
  11. 颠覆式编程:软件2.0
  12. 国内ERP系统和SAP系统架构存在哪些差异?
  13. 影像信息提取之——多时相影像动态检测
  14. git fatal: schannel: next InitializeSecurityContext failed: SEC E CERT EXPIRED (0x80090328)
  15. 为程序员写的Reed-Solomon码解释
  16. python关于变量的声明
  17. 关于考研的几个潜规则
  18. 微信小程序实现短信认证功能
  19. 关于串口波特率的的记录
  20. Mellanox Infiniband卡切换IB/Ethernet模式

热门文章

  1. 别再不懂IP代理了!
  2. 243 mysql获取某个表中除了某个字段名外的所有字段名
  3. java 修改文件内容_用Java修改现有文件内容
  4. 教程:在Vivado中指定VSCode作为文本编辑器
  5. 从零开始搭建saas系统(1)
  6. 再一篇相当中肯的文字
  7. tftp--实现服务器与客户端的下载与上传
  8. Microsoft Word 通过通配符替换图片下标文字
  9. 华为(HuaWei)虚拟按键的判断和监听
  10. 推荐系统中的矩阵分解| 奇异值分解及改进、因子分解机