当前位置: 首页 > news >正文

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&#xff0c;且从下图中可以看到&#xff0c;奇偶行是各自挨在一起的。 1.2 自定义表格过滤示例图 下图添加两列条件&#xff08;当前数据大于当前列条件才返回true&#xff0c;且多个列…...

电商(强一致性系统)的场景设计

领域拆分&#xff1a;如何合理地拆分系统&#xff1f; 一般来说&#xff0c;强一致性的系统都会牵扯到“锁争抢”等技术点&#xff0c;有较大的性能瓶颈&#xff0c;而电商时常做秒杀活动&#xff0c;这对系统的要求更高。业内在对电商系统做改造时&#xff0c;通常会从三个方面…...

算法与数据结构(一)

一、时间复杂度 一个操作如果和样本的数据量没有关系&#xff0c;每次都是固定时间内完成的操作&#xff0c;叫做常数操作。 时间复杂度为一个算法流程中&#xff0c;常数操作数量的一个指标。常用O(读作big O)来表示。具体来说&#xff0c;这个算法流程中&#xff0c;发生了多…...

【Python】元组如何创建?

嗨害大家好鸭&#xff01;我是小熊猫~ Python 元组 Python 的元组与列表类似&#xff0c; 不同之处在于元组的元素不能修改。 元组使用小括号&#xff0c;列表使用方括号。 元组创建很简单&#xff0c;只需要在括号中添加元素&#xff0c; 并使用逗号隔开即可。 如下实例…...

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个数字只有一个&#xff0c;其他数字都有两个。找出这两个数字。a, b 用HashMap记录就不说了。 这里记录一下用异或的方式解决。 由于异或特性为自己异或自己为0。a^a 0;所以可以异或数组中的所有数字得出 a^b 的结果&#xff0c;其他相同的都消掉…...

python支持的操作系统有哪些

支持python开发环境的系统有Linux、OSX和windows&#xff0c;以及所有主要的操作系统中。 Linux&#xff0c;Linux系统是为编程而设计的&#xff0c;因此在大多数Linux计算机中&#xff0c;都默认安装了Python。编写和维护Linux的人认为会使用这种系统进行编程。要在Linux中运…...

S3C2440开发环境搭建

拿出了之前的S3C2440开发板&#xff0c;然后把移植uboot、移植内核、制作根文件系统、设备树编写驱动等几项再做一遍&#xff0c;这篇文章先记录下环境搭建过程&#xff0c;以及先把现成的uboot、内核、根文件系统下载进去&#xff0c;看看开发板还能不能用&#xff0c;先熟悉一…...

软件测试之测试用例

测试用例 1. 测试用例定义 测试用例又叫做test case&#xff0c;是为某个特殊目标而编制的一组测试输入、执行条件以及预期结果,以便测试某个程序路径或核实是否满足某个特定需求。 2. 编写测试用例的原因 2.1 理清思路&#xff0c;避免遗漏 如果测试的项目大而复杂&#…...

null和undefined的区别有哪些?

null和undefined的区别有哪些&#xff1f;相同点不同点undefinednull总结相同点 1.null和undefined都是js的基本数据类型 2.undefined和null都是假值&#xff08;falsy&#xff09;,都能作为条件进行判断&#xff0c;所以在绝大多数情况下两者在使用上没有区别 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的生命周期里&#xff0c;每个类只会被加载一次。 类加载的原则&#xf…...

ledcode【用队列实现栈】

目录 题目描述&#xff1a; 解析题目 代码解析 1.封装一个队列 1.2封装带两个队列的结构体 1.3封装指向队列的结构体 1.4入栈函数实现 1.5出栈函数实现 1.6取栈顶数据 1.7判空函数实现 题目描述&#xff1a; 解析题目 这个题我是用c语言写的&#xff0c;所以队列的pu…...

【基础算法】双指针----字符串删减

&#x1f339;作者:云小逸 &#x1f4dd;个人主页:云小逸的主页 &#x1f4dd;Github:云小逸的Github &#x1f91f;motto:要敢于一个人默默的面对自己&#xff0c;强大自己才是核心。不要等到什么都没有了&#xff0c;才下定决心去做。种一颗树&#xff0c;最好的时间是十年前…...

Billu靶场黑盒盲打——思路和详解

一、信息收集 1、探测内网主机IP可以使用各种扫描工具比如nmap&#xff0c;我这里用的是自己编写的。 nmap -n 192.168.12.0/24 #扫描IP&#xff0c;发现目标主机 2、先不着急&#xff0c;先收集一波它的端口&#xff08;无果&#xff09; nmap -n 192.168.12.136 -p 1-10000…...

【2363. 合并相似的物品】

来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 给你两个二维整数数组 items1 和 items2 &#xff0c;表示两个物品集合。每个数组 items 有以下特质&#xff1a; items[i] [valuei, weighti] 其中 valuei 表示第 i 件物品的 价值 &#xff0c;we…...

【C++提高编程】C++全栈体系(二十四)

C提高编程 第三章 STL - 常用容器 九、map/ multimap容器 1. map基本概念 简介&#xff1a; map中所有元素都是pairpair中第一个元素为key&#xff08;键值&#xff09;&#xff0c;起到索引作用&#xff0c;第二个元素为value&#xff08;实值&#xff09;所有元素都会根…...

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】使…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

毫米波雷达基础理论(3D+4D)

3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文&#xff1a; 一文入门汽车毫米波雷达基本原理 &#xff1a;https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !

我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...

ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]

报错信息&#xff1a;libc.so.6: cannot open shared object file: No such file or directory&#xff1a; #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...

如何在Windows本机安装Python并确保与Python.NET兼容

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...