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开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓
3.过滤方法1-使用setFilterKeyColumn()过滤列
首先需要通过void QsortFilterProxyModel::setFilterRegExp(const QRegExp ®Exp)来设置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()重新更新过滤器即可.
弊端:
所以,如果要使用联合多列过滤,建议使用过滤方法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()重新更新过滤器即可.
注意事项:
5.代码示例
model采用上章代码的CustomModel为例.支持筛选多列、筛选模式支持:或方式、与方式、
界面实现如下所示:

- #ifndef SORTFILTERPROXYMODEL_H
- #define SORTFILTERPROXYMODEL_H
-
- #include
- #include
- #include
-
- class SortFilterProxyModel : public QSortFilterProxyModel
- {
- Q_OBJECT
-
- virtual 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;
- else
- return 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;
-
- }
本文福利,莬费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓