Qt之QTableView自定义排序/过滤(QSortFilterProxyModel实现,含源码+注释)
一、效果示例图
1.1 自定义表格排序示例图
本文过滤条件为行索引取余2等于0时返回true,且从下图中可以看到,奇偶行是各自挨在一起的。
1.2 自定义表格过滤示例图
下图添加两列条件(当前数据大于当前列条件才返回true,且多个列条件为且关系);下方添加条件分别为,”0列,条件值50“,”2列条件值40“,综合下来为0列值大于50且2列值大于40则返回true
二、相关理解
被动触发:不论是排序还是过滤,都会在添加数据的时候触发自定义排序/过滤函数;
主动触发:排序,可通过数据模型或过滤模型的sort函数触发;过滤,可通过setFilterRegExp函数触发。(此处说的两个函数主动调用后会运行自定义排序/过滤条件,前提是对应的函数有重写)
过滤:此外,除开本文写的filterAcceptsRow函数还有filterAcceptsColumn函数,其触发条件与filterAcceptsRow一致
三、源码
CMainWindow.h
#ifndef CMAINWINDOW_H
#define CMAINWINDOW_H#include "CSortFilterProxyModel.h"#include <QMainWindow>
#include <QStandardItemModel>namespace Ui {
class CMainWindow;
}class CMainWindow : public QMainWindow
{Q_OBJECTpublic:explicit CMainWindow(QWidget *parent = nullptr);~CMainWindow();private slots:/*** @brief on_btnCustom_clicked 自定义条件添加响应函数*/void on_btnCustom_clicked();/*** @brief on_btnInitData_clicked 数据初始化响应函数*/void on_btnInitData_clicked();private:Ui::CMainWindow *ui;QStandardItemModel *m_model; // 数据模型CSortFilterProxyModel *m_customFilterModel; // 自定义过滤器模型
};#endif // CMAINWINDOW_H
CMainWindow.cpp
#include "CMainWindow.h"
#include "ui_CMainWindow.h"#include <QMessageBox>CMainWindow::CMainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::CMainWindow)
{ui->setupUi(this);// 数据模型对象创建m_model = new QStandardItemModel;// 自定义过滤器类对象创建m_customFilterModel = new CSortFilterProxyModel;// 设置数据源模型m_customFilterModel->setSourceModel(m_model);// 先将正常数据模型类设置到表格中ui->tableView->setModel(m_customFilterModel);// 设置表格可排序(设置过后通过自定义lessThan函数排序)ui->tableView->setSortingEnabled(true);
}CMainWindow::~CMainWindow()
{// 释放内存空间delete m_customFilterModel;delete m_model;delete ui;
}void CMainWindow::on_btnCustom_clicked()
{// 获取条件字符串QString colStr = ui->editCol->text();QString conditionStr = ui->editCondition->text();if(colStr.isEmpty() || conditionStr.isEmpty()){QMessageBox::information(this, "提示", "条件值为空,请输入条件");return;}// 获取条件并将其添加到自定义模型中m_customFilterModel->appendCondition(ui->editCol->text().toInt(), ui->editCondition->text().toInt());// 条件列和条件值编辑框清空ui->editCol->clear();ui->editCondition->clear();// 通过设置过滤条件触发自定义过滤(此处条件不会影响自定义过滤)m_customFilterModel->setFilterRegExp("");
}void CMainWindow::on_btnInitData_clicked()
{// 虽然表格上是过滤模型,但是数据还是得设置到数据模型上才可for(int row = 0; row != 10; ++row){for(int col = 0; col != 10; ++col){// 设置当前行列的item, 并初始化随机值m_model->setItem(row, col, new QStandardItem(QString::number(rand() % 100)));}}
}
CMainWindow.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>CMainWindow</class><widget class="QMainWindow" name="CMainWindow"><property name="geometry"><rect><x>0</x><y>0</y><width>821</width><height>525</height></rect></property><property name="windowTitle"><string>CMainWindow</string></property><widget class="QWidget" name="centralWidget"><layout class="QGridLayout" name="gridLayout"><item row="2" column="1"><widget class="QLineEdit" name="editCondition"><property name="text"><string/></property><property name="placeholderText"><string>条件值</string></property></widget></item><item row="2" column="0"><widget class="QLineEdit" name="editCol"><property name="text"><string/></property><property name="placeholderText"><string>列</string></property></widget></item><item row="4" column="0" colspan="3"><widget class="QTableView" name="tableView"/></item><item row="1" column="0"><widget class="QPushButton" name="btnInitData"><property name="text"><string>初始化数据</string></property></widget></item><item row="1" column="1"><widget class="QPushButton" name="btnCustom"><property name="text"><string>添加自定义模型条件</string></property></widget></item></layout></widget><widget class="QMenuBar" name="menuBar"><property name="geometry"><rect><x>0</x><y>0</y><width>821</width><height>23</height></rect></property></widget><widget class="QToolBar" name="mainToolBar"><attribute name="toolBarArea"><enum>TopToolBarArea</enum></attribute><attribute name="toolBarBreak"><bool>false</bool></attribute></widget><widget class="QStatusBar" name="statusBar"/></widget><layoutdefault spacing="6" margin="11"/><resources/><connections/>
</ui>
CSortFilterProxyModel.h
#ifndef CSORTFILTERPROXYMODEL_H
#define CSORTFILTERPROXYMODEL_H#include <QSortFilterProxyModel>class CSortFilterProxyModel : public QSortFilterProxyModel
{Q_OBJECT
public:explicit CSortFilterProxyModel(QObject *parent = nullptr);/*** @brief appendCondition 追加条件函数* @param col 条件列* @param val 条件值*/void appendCondition(int col, int val);// QSortFilterProxyModel interface
protected:/*** @brief filterAcceptsRow 过滤行函数* @param source_row 当前行索引* @param source_parent 当前行父对象(没有则为空)* @return 过滤结果*/bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;/*** @brief lessThan 排序函数* @param source_left 比较的左值* @param source_right 比较的右值* @return 比较结果*/bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const;private:QMap<int, int> m_mapFilterCondition; // 条件值保存容器<列, 条件值>};#endif // CSORTFILTERPROXYMODEL_H
CSortFilterProxyModel.cpp
#include "CSortFilterProxyModel.h"#include <QDebug>
#include <QStandardItemModel>CSortFilterProxyModel::CSortFilterProxyModel(QObject *parent) : QSortFilterProxyModel(parent)
{}void CSortFilterProxyModel::appendCondition(int col, int val)
{// 直接赋值(不存在会添加,已存在会更新)m_mapFilterCondition[col] = val;
}bool CSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{// 定义返回值变量bool ret = true;// 获取数据源模型对象,并转换为需要的类型模板QStandardItemModel *srcModel = dynamic_cast<QStandardItemModel *>(sourceModel());if(nullptr != srcModel){foreach(int col, m_mapFilterCondition.keys()){// 获取当前的item对象QStandardItem *item = srcModel->item(source_row, col);// 此时对应item不为空且整形值要小于条件值才显示if(nullptr != item && m_mapFilterCondition[col] > item->text().toInt()){ret = false;break;}}}return ret;
}bool CSortFilterProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{// 当前行为取余2等于0时返回true(就是说默认降序排序偶数行在前)return 0 == source_left.row() % 2;
}
总结
虽然自定义排序和过滤比较简单,但是在项目中非常实用,如需要将某行/列置顶,特殊条件过滤等。
友情提示——哪里看不懂可私哦,让我们一起互相进步吧
(创作不易,请留下一个免费的赞叭 谢谢 o/)
注:文章为作者编程过程中所遇到的问题和总结,内容仅供参考,若有错误欢迎指出。
注:如有侵权,请联系作者删除
相关文章:
Qt之QTableView自定义排序/过滤(QSortFilterProxyModel实现,含源码+注释)
一、效果示例图 1.1 自定义表格排序示例图 本文过滤条件为行索引取余2等于0时返回true,且从下图中可以看到,奇偶行是各自挨在一起的。 1.2 自定义表格过滤示例图 下图添加两列条件(当前数据大于当前列条件才返回true,且多个列…...
电商(强一致性系统)的场景设计
领域拆分:如何合理地拆分系统? 一般来说,强一致性的系统都会牵扯到“锁争抢”等技术点,有较大的性能瓶颈,而电商时常做秒杀活动,这对系统的要求更高。业内在对电商系统做改造时,通常会从三个方面…...
算法与数据结构(一)
一、时间复杂度 一个操作如果和样本的数据量没有关系,每次都是固定时间内完成的操作,叫做常数操作。 时间复杂度为一个算法流程中,常数操作数量的一个指标。常用O(读作big O)来表示。具体来说,这个算法流程中,发生了多…...
【Python】元组如何创建?
嗨害大家好鸭!我是小熊猫~ Python 元组 Python 的元组与列表类似, 不同之处在于元组的元素不能修改。 元组使用小括号,列表使用方括号。 元组创建很简单,只需要在括号中添加元素, 并使用逗号隔开即可。 如下实例…...
qt操作文件以及字符串转换
//从文件加载英文属性与中文属性对照表QFile file(":/propertyname.txt");if (file.open(QFile::ReadOnly)) {//QTextStream方法读取速度至少快百分之30#if 0while(!file.atEnd()) {QString line file.readLine();appendName(line);}#elseQTextStream in(&file)…...
数组中只出现一次的两个数字(异或法思路)
题目简介 一个数组中只有2个数字只有一个,其他数字都有两个。找出这两个数字。a, b 用HashMap记录就不说了。 这里记录一下用异或的方式解决。 由于异或特性为自己异或自己为0。a^a 0;所以可以异或数组中的所有数字得出 a^b 的结果,其他相同的都消掉…...
python支持的操作系统有哪些
支持python开发环境的系统有Linux、OSX和windows,以及所有主要的操作系统中。 Linux,Linux系统是为编程而设计的,因此在大多数Linux计算机中,都默认安装了Python。编写和维护Linux的人认为会使用这种系统进行编程。要在Linux中运…...
S3C2440开发环境搭建
拿出了之前的S3C2440开发板,然后把移植uboot、移植内核、制作根文件系统、设备树编写驱动等几项再做一遍,这篇文章先记录下环境搭建过程,以及先把现成的uboot、内核、根文件系统下载进去,看看开发板还能不能用,先熟悉一…...
软件测试之测试用例
测试用例 1. 测试用例定义 测试用例又叫做test case,是为某个特殊目标而编制的一组测试输入、执行条件以及预期结果,以便测试某个程序路径或核实是否满足某个特定需求。 2. 编写测试用例的原因 2.1 理清思路,避免遗漏 如果测试的项目大而复杂&#…...
null和undefined的区别有哪些?
null和undefined的区别有哪些?相同点不同点undefinednull总结相同点 1.null和undefined都是js的基本数据类型 2.undefined和null都是假值(falsy),都能作为条件进行判断,所以在绝大多数情况下两者在使用上没有区别 if(undefined)…...
【强烈建议收藏:计算机网络面试专题:HTTP协议、HTTP请求报文和响应报文、HTTP请求报文常用字段、HTTP请求方法、HTTP响应码】
一.知识回顾 之前我们一起学习了HTTP1.0、HTTP1.1、HTTP2.0协议之前的区别、以及URL地址栏中输入网址到页面展示的全过程&&DNS域名解析的过程、HTTP协议基本概念以及通信过程、HTTPS基本概念、SSL加密原理、通信过程、中间人攻击问题、HTTP协议和HTTPS协议区别。接下来…...
关于Java中的静态块讲解
文章目录类的加载特性与时机类加载的特性类加载的时机static的三个常用地方什么是静态块?特点写法静态块 static怎么用?类的加载特性与时机 在介绍static之前可以先看看类的相关 类加载的特性 在JVM的生命周期里,每个类只会被加载一次。 类加载的原则…...
ledcode【用队列实现栈】
目录 题目描述: 解析题目 代码解析 1.封装一个队列 1.2封装带两个队列的结构体 1.3封装指向队列的结构体 1.4入栈函数实现 1.5出栈函数实现 1.6取栈顶数据 1.7判空函数实现 题目描述: 解析题目 这个题我是用c语言写的,所以队列的pu…...
【基础算法】双指针----字符串删减
🌹作者:云小逸 📝个人主页:云小逸的主页 📝Github:云小逸的Github 🤟motto:要敢于一个人默默的面对自己,强大自己才是核心。不要等到什么都没有了,才下定决心去做。种一颗树,最好的时间是十年前…...
Billu靶场黑盒盲打——思路和详解
一、信息收集 1、探测内网主机IP可以使用各种扫描工具比如nmap,我这里用的是自己编写的。 nmap -n 192.168.12.0/24 #扫描IP,发现目标主机 2、先不着急,先收集一波它的端口(无果) nmap -n 192.168.12.136 -p 1-10000…...
【2363. 合并相似的物品】
来源:力扣(LeetCode) 描述: 给你两个二维整数数组 items1 和 items2 ,表示两个物品集合。每个数组 items 有以下特质: items[i] [valuei, weighti] 其中 valuei 表示第 i 件物品的 价值 ,we…...
【C++提高编程】C++全栈体系(二十四)
C提高编程 第三章 STL - 常用容器 九、map/ multimap容器 1. map基本概念 简介: map中所有元素都是pairpair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)所有元素都会根…...
c++11 标准模板(STL)(std::unordered_set)(十一)
定义于头文件 <unordered_set> template< class Key, class Hash std::hash<Key>, class KeyEqual std::equal_to<Key>, class Allocator std::allocator<Key> > class unordered_set;(1)(C11 起)namespace pmr { templ…...
AI/CV大厂笔试LeetCode高频考题之基础核心知识点
AI/CV互联网大厂笔试LeetCode高频考题之基础核心知识点算法复习1、二叉树的遍历2、回溯算法3、二分搜索4、滑动窗口算法题5、经典动态规划6、动态规划答疑篇6.1、总结一下如何找到动态规划的状态转移关系7、编辑距离8、戳气球问题9、最长公共子序列 Longest Common Subsequence…...
华为OD机试题,用 Java 解【静态扫描最优成本】问题
最近更新的博客 华为OD机试题,用 Java 解【停车场车辆统计】问题华为OD机试题,用 Java 解【字符串变换最小字符串】问题华为OD机试题,用 Java 解【计算最大乘积】问题华为OD机试题,用 Java 解【DNA 序列】问题华为OD机试 - 组成最大数(Java) | 机试题算法思路 【2023】使…...
常见无线技术方案介绍
无线技术 无线网络大体有两种:WAN(广域网)、PAN(个人区域网)。 对于LoRa,NB-IoT,2G / 3G / 4G等无线技术,通常传输距离超过1 km,因此它们主要用于广域网(WA…...
收获满满的2022年
收到csdn官方的证书,感谢官方的认可!...
react的生命周期
目录 一、初始化阶段 constructor() static getDerivedStateFromProps() componentWillMount() / UNSAFE_componentWillMount() render(): componentDidMount() 二、运行阶段 componentWillUpdate() / UNSAFE_componentWillUpdate() render() getSnapsh…...
scanpy 单细胞分析API接口使用案例
参考:https://zhuanlan.zhihu.com/p/537206999 https://scanpy.readthedocs.io/en/stable/api.html scanpy python包主要分四个模块: 1)read 读写模块、 https://scanpy.readthedocs.io/en/stable/api.html#reading 2)pp Prepr…...
【Vue3 第二十一章】Teleport组件传送
一、基本使用场景 有时我们可能会遇到这样的场景:一个组件模板的一部分在逻辑上从属于该组件,但从整个应用视图的角度来看,它在 DOM 中应该被渲染在整个 Vue 应用外部的其他地方。 这类场景最常见的例子就是全屏的模态框。理想情况下&#…...
在 Windows Subsystem for Linux (WSL2) 的 Ubuntu 系统上配置 Vulkan 开发环境
在 Windows Subsystem for Linux (WSL2) 的 Ubuntu 系统上配置 Vulkan 开发环境Vulkan Tutorial https://vulkan-tutorial.com/ Development environment - Linux https://vulkan-tutorial.com/Development_environment 1. Vulkan - Cross platform 3D Graphics https://www…...
放苹果HJ61
入门题目 把m个同样的苹果放在n个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?注意:如果有7个苹果和3个盘子,(5,1,1)和(1,5&#…...
Windows下,OPC UA移植,open62541移植
OPC通信标准的核心是互通性 (Interoperability) 和标准化 (Standardization) 问题。传统的OPC技术在控制级别很好地解决了硬件设备间的互通性问题,在企业层面的通信标准化是同样需要的。OPC UA之前的访问规范都是基于微软的COM/DCOM技术, 这会给新增层面的通信带来不可根除的…...
【Tomcat与Servlet篇1】认识Tomcat与Maven
目录 一、什么是Tomcat 二、Tomcat的几个重要目录 conf文件编辑 Server.xml logs文件 Webapps目录 三、如何使用Tomcat 但是,如果出现了点击之后进行闪退的情况,那又是怎么回事呢? 原因1:环境变量没有配置 原因2&#…...
C++类和对象:拷贝构造函数和运算符重载
目录 一. 拷贝构造函数 1.1 什么是拷贝构造函数 1.2 编译器默认生成的拷贝构造函数 1.3 拷贝构造函数特性总结 二. 运算符重载 2.1 运算符重载概述 2.2 比较运算符重载(> > < <) 2.2.1 >运算符的重载 2.2.2 运算符的重载 2.…...
模板网站建设价格/网络营销的特点不包括
陌生了!以前痴迷的技术,可我仍想拾起!转载于:https://blog.51cto.com/mmgsdxb/317666...
织梦手机网站有广告/太原seo网络优化招聘网
模板下载: 链接:https://pan.baidu.com/s/1_4z_Lg51jMT87RrRM6Qs3g 提取码:2gns 对MDK的AC6也做了支持: https://www.cnblogs.com/armfly/p/11256067.html 1、MDK使用MDK5.26及其以上版本。 2、IAR使用IAR8.30及其以上版本。 3…...
东莞专业网站建设/网络seo公司
如何修复Linux I/O写入性能问题使用top和iotop分析Linux写入性能问题,本文将解释如何解决性能问题。 如果你已经使用top和iotop确定存在写入性能问题,那你需要做几件事。首先是服务器的设计。许多服务器都安装在一个巨大的分区里,集成了操作系…...
wordpress add filter/贵州seo推广
牙膏膨胀市场的企业竞争态势 该报告涉及的主要国际市场参与者有CCA Industries、Church & Dwight、Colgate-Palmolive、Unilever、Gaba Holding、Dabur India、Hindustan Unilever、Henkel、Johnson and Johnson、LG Household & Health、Lion Corporation、Procter &a…...
做微商卖产品在哪个网站销量能好点/千峰培训出来好就业吗
用rmoutliers()函数即可移除数据组中的离群值,可作数据清洗的初步方法。如果是移除一类数据,可以用方差分析、主成分析、相关性分析、皮尔逊相关系数等方法。 语法 最简单的用法是第一个,其中A是输入的数据,B是输出的数据。 B …...
新浪云 wordpress/seo作弊
题目描述: 在一个字符串(1<字符串长度<10000,全部由大写字母组成)中找到第一个只出现一次的字符。 如输入 abaccdeff,则输出 b。 输入: 输入有多组数据 每一组输入一个字符串。 输出: 输出第一个只出现一次的…...