QT教程:QSortFilterProxyModel代理实现自定义排序、联合过滤

QT教程:QSortFilterProxyModel代理实现自定义排序、联合过滤1 QsortFilterP 介绍 QsortFilterP 类用来为 model 和 view 之间提供强大的排序和过滤支持 将模型排序或者过滤后在视图上显示 并且无需对模型中的数据进行任何转换 也无需对模型在中数

欢迎大家来到IT世界,在知识的湖畔探索吧!

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); //在视图中安装代理

欢迎大家来到IT世界,在知识的湖畔探索吧!

2.QSortFilterProxyModel自定义排序

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

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

lessThan()使用示例:

欢迎大家来到IT世界,在知识的湖畔探索吧!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开发教程学习资料,点击下方链接莬费领取↓↓,先码住不迷路~】

点击→领取「链接」

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+)?#34;, 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()函数.

示例代码如下所示:

欢迎大家来到IT世界,在知识的湖畔探索吧!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+)?#34;); //安装过滤器

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

注意事项:

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

5.代码示例

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

界面实现如下所示:

QT教程:QSortFilterProxyModel代理实现自定义排序、联合过滤



欢迎大家来到IT世界,在知识的湖畔探索吧!

欢迎大家来到IT世界,在知识的湖畔探索吧!#ifndef SORTFILTERPROXYMODEL_H #define SORTFILTERPROXYMODEL_H #include <QObject> #include <QSortFilterProxyModel> #include <QList> 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如下所示:

【领QT开发教程学习资料,点击下方链接莬费领取↓↓,先码住不迷路~】

点击→领取「链接」

#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; }

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/128101.html

(0)
上一篇 16分钟前
下一篇 2024年 11月 26日 上午9:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信