Qt4用子类化ProxyModel和子类化MainWindow实现全表筛选,中文排序和复制粘贴

目录

1 需求

2 子类化ProxyModel实现全表筛选

3 字符串列表实现中文排序

3.1 Qt5中文排序

3.2 Qt4排序

4 表格的复制粘贴

5 应用


1 需求

模型视图编程是Qt开发的基本功,其中有几个关键问题需要解决:

  • 全表筛选,或者说多列搜索
  • 中文排序问题
  • 表格内容的复制粘贴

下面就这两个问题进行阐述。

2 子类化ProxyModel实现全表筛选

QSortFilterProxyModel是对模型功能的补充,可用于实现排序,筛选等。但是其筛选功能只能对某列进行,代码如下:

proxyModel->setFilterKeyColumn(3);

指定列搜索没法达到全表筛选的功能需求,为达到这一点,需要子类化QSortFilterProxyModel,并重写filterAcceptsRow函数。

下面是代码:

proxymodel.h

#ifndef PROXYMODEL_H
#define PROXYMODEL_H#include <QSortFilterProxyModel>class ProxyModel : public QSortFilterProxyModel
{Q_OBJECTpublic:ProxyModel(QObject *parent);protected:bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
};#endif // PROXYMODEL_H

proxymodel.cpp

#include "proxymodel.h"ProxyModel::ProxyModel(QObject *parent)
: QSortFilterProxyModel(parent)
{
}// 重写filterAcceptsRow成员函数 实现全表查询 只要该行有1个以上单元符合条件就显示
bool ProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{// 获取源模型的列数int colCount = sourceModel()->columnCount();// 循环该行每1列QString cell;for(int i = 0; i<colCount; i++){cell = sourceModel()->index(source_row, i, source_parent).data(Qt::DisplayRole).toString();// 若该列符合条件 则返回真if(cell.contains(this->filterRegExp()))return true;}// 若各列都不为真 则返回假return false;
}

这段子类化代码在CSDN其他博客上都有相关描述,但很多还重写了一些其他函数,单纯从全表筛选角度看,是没有必要的,只要重写filterAcceptsRow函数即可。基本逻辑为:

先获取源模型有多少列。

遍历列,逐个判断当前单元是否符合正则化要求,如果符合,直接返回真,就是说这一行是要显示的。

如果遍历完都没有符合项,就返回假,说明这一行不符合要求,不用显示。

之后在视图上,就完成了全表筛选。

如果要筛选指定列,或者共同项,对这个逻辑做代换即可,比如不要遍历所有列,只检查指定列;或者将判断条件从或||变成和&&

3 字符串列表实现中文排序

Qt自带的排序功能只能实现数字和字母排序,要实现中文排序,对QT4和QT5有两种不同的实现方法。

3.1 Qt5中文排序

可以借助QLocale类(没经过验证)

具体代码如下:

QLocale loc(QLocale::Chinese, QLocale::China);
loc.languageToString(QLocale::Chinese);
QCollator qoc(loc);
qSort(listData.begin(), listData.end(), qoc); //正序排序

还有另一个写法:

// 创建一个中文字符串列表
QStringList list;
list << "赵" << "钱" << "孙" << "李" << "周" << "吴" << "郑" << "王";// 使用 QCollator 进行排序
QCollator collator;
collator.setNumericMode(true);   // 数字模式
collator.setCaseSensitivity(Qt::CaseInsensitive);   // 不区分大小写
std::sort(list.begin(), list.end(), collator);

这两个写法都因为没装qt5环境,没经过验证,但思路是可行的。

3.2 Qt4排序

Qt4因为没这个库,只能通过写子程序的方式实现。

代码如下:


// 中文排序
QStringList MainWindow::sort(QStringList stringList)
{QMap<QByteArray,QString> barryMap;QTextCodec* codec = QTextCodec::codecForName("GBK");if(codec){for(int i=0; i<stringList.count(); i++){QString text = stringList.at(i);if( isContainsHz(text)){QByteArray barr = codec->fromUnicode(text);barryMap.insert(barr, text);}else{barryMap.insert(text.toLatin1(), text);}}}stringList.clear();stringList = barryMap.values();return stringList;
}// 中文排序 子程序
bool MainWindow::isContainsHz(const QString text)
{return text.contains( QRegExp("[\\x4e00-\\x9fa5]+") );
}

这个排序可实现对QStringList的中文排序,注意是字符串列表而不是模型。在对QStringList排序后,还需要加载到模型中代入视图显示。

4 表格的复制粘贴

tableview的复制粘贴需要进行子类化,但我们编写小程序时,如果不子类化tableview,也可以直接写在mainwindow里,这里需要对用到的模型变量稍微做下修改即可。

代码如下:


// 实现ctrl+c ctrl+v 选中单元复制粘贴
void MainWindow::keyPressEvent(QKeyEvent *keyEvent)
{if(keyEvent->matches(QKeySequence::Copy))//复制{QModelIndexList indexList = ui->table->selectionModel()->selectedIndexes();if(indexList.isEmpty())return;int startRow = indexList.first().row();int endRow = indexList.last().row();int startCol = indexList.first().column();int endCol = indexList.last().column();QStringList clipboardTextList;for(int i = startRow;i <= endRow;i++){QStringList rowText;for(int j = startCol;j <= endCol;j++){rowText.append(model->data(model->index(i,j)).toString());}clipboardTextList.append(rowText.join("\t"));}QString clipboardText = clipboardTextList.join("\n" );QApplication::clipboard()->setText(clipboardText);}else if (keyEvent->matches(QKeySequence::Paste)){QString clipboardText = QApplication::clipboard()->text();if(clipboardText.isEmpty())return;QStringList rowTextList = clipboardText.split('\n');if(rowTextList.last().isEmpty())//从word或者excel复制的内容后面可能会带'\n',导致split出来后面有个空字符串。rowTextList.removeLast();QModelIndexList indexList = ui->table->selectionModel()->selectedIndexes();if(indexList.isEmpty())return;QModelIndex startIndex = indexList.first();for(int i = 0;i < rowTextList.size();i++){QStringList itemTextList = rowTextList.at(i).split('\t');for(int j = 0;j < itemTextList.size();j++){QModelIndex curIndex = model->index(i + startIndex.row(),j + startIndex.column());if(curIndex.isValid()){model->setData(curIndex,itemTextList.at(j));}}}}
}

用的时候,要根据自己的程序把里面的共有变量进行替换。

5 应用

下面根据上面提到的技术,编写了一个标准规范浏览器,目的是实现标准规范文件的分类展示,同时还能实现全表搜索。

通过在构造函数中读取数据库,将文件加载到表格中,再对分类进行解析,经过去重复,排序,形成左侧分类栏。点击分类可实现proxymodel的筛选展示。在搜索工具条也可以实现全表搜索。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/171219.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux服务器SSH客户端断开后保持程序继续运行的方法

目录 1. nohup 命令&#xff1a; 2. tmux 或 screen&#xff1a; 3 final shell 断开后服务器如何继续执行令&#xff1f; 方法一&#xff1a;使用 nohup 命令 方法二&#xff1a;将命令放在后台执行 4 你可以使用 jobs 命令查看当前终端中正在后台运行的任务 &#xff…

决策树(第四周)

一、决策树基本原理 如下图所示&#xff0c;是一个用来辨别是否是猫的二分类器。输入值有三个&#xff08;x1&#xff0c;x2&#xff0c;x3&#xff09;&#xff08;耳朵形状&#xff0c;脸形状&#xff0c;胡须&#xff09;&#xff0c;其中x1{尖的&#xff0c;圆的}&#xf…

叠加原理(superposition principle)、线性系统

叠加原理&#xff08;superposition principle&#xff09;&#xff1a;指对一个系统而言&#xff0c;两个或多个输入产生的输出&#xff0c;等于这几个输入单独引起的输出的和&#xff0c;即输入的叠加等于各输入单独引起的输出的叠加。 线性系统&#xff1a;一个系统&#x…

常用的Linux的指令

目录 常用指令 1、文件和目录操作&#xff1a; 2、文件查看和编辑 3、系统信息 4、进程管理 5、用户和权限 6、网络操作 7、压缩和解压 8、软件包管理 常用指令 1、文件和目录操作&#xff1a; ls&#xff1a;列出目录内容 cd&#xff1a; 切换目录 pwd&#xff1a;显…

十分钟让你搞懂JVM中的GC垃圾回收机制(分代回收)

文章目录 0. 为什么要有垃圾回收?1. 垃圾回收哪个内存区域?2. 如何找到垃圾(死亡对象的判断)2.1 引用计数法2.2 可达性分析法2.3 两种算法的差别 3. 如何清理垃圾(死亡对象的回收)3.1 标记-清楚法3.2 复制法3.3 标记-整理法 4. JVM使用的回收方法4.1 什么是分代回收4.2 哪些对…

JVM——几种常见的对象引用

目录 1. 软引用软引用的使用场景-缓存 2.弱引用3.虚引用和终结器引用 可达性算法中描述的对象引用&#xff0c;一般指的是强引用&#xff0c;即是GCRoot对象对普通对象有引用关系&#xff0c;只要这层关系存在&#xff0c; 普通对象就不会被回收。除了强引用之外&#xff0c;Ja…

C++局域网从服务器获取已连接用户的列表(linux to linux)

目录 服务器端 代码 客户端 代码解析 服务器端 原理 遇到的阻碍以及解决办法 客户端 原理 遇到的阻碍以及解决办法 运行结果截图 总结 服务器端 代码 #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet…

深入了解 Pinia:现代 Vue 应用的状态管理利器

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

【Python】用三种方法创建tkinter桌面窗口

Python的tkinter是Python的标准GUI库之一&#xff0c;它是一个开源的、跨平台的GUI工具包&#xff0c;可以用于创建桌面应用程序。 tkinter提供了许多常见的GUI组件&#xff0c;例如按钮、文本框、标签、列表框等等&#xff0c;可以轻松地创建各种类型的桌面应用程序。它还支持…

云服务器上部署 Web 项目及端口异常处理

文章目录 1. 在云服务器的 MySQL(MariaDB) 中, 建库建表2. 微调代码3. 打包4. 把 war 包 拷贝到云服务器上端口被占用处理 1. 在云服务器的 MySQL(MariaDB) 中, 建库建表 在云服务器中进入 MySQL mysql -u root -p把之前本地写好的 SQL 代码一粘贴即可 例如: -- 这个文件主要…

线性表,也是Java中数组的知识点!

线性表定义&#xff1a; 由n (n≥0)个数据特性相同的元素构成的有限序列称为线性表&#xff0c;(n0)的时候被称为空表。 线性表的顺序表示 线性表的顺序存储又被称为顺序表 优点 无需为表示表中元素之间的逻辑关系而增加额外的存储空间可以随意读取任意位置的元素 缺点 插入…

人力资源管理后台 === 登陆+主页灵鉴权

目录 1. 分析登录流程 2. Vuex中用户模块的实现 3.Vue-cli代理解决跨域 4.axios封装 5.环境区分 6. 登录联调 7.主页权限验证-鉴权 1. 分析登录流程 传统思路都是登录校验通过之后&#xff0c;直接调用接口&#xff0c;获取token之后&#xff0c;跳转到主页。 vue-elemen…

html实现360度产品预览(附源码)

文章目录 1.设计来源1.1 拖动汽车产品旋转1.2 汽车产品自动控制 2.效果和源码2.1 动态效果2.2 源代码 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/details/134613931 html实现360度产品预览&#xff08;附源码&…

VUE留言板

效果预览图 完整代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>作业</title><styl…

Flutter | TextField长按时选项菜单复制、粘贴显示为英文问题解决

Flutter | TextField长按时选项菜单复制、粘贴显示为英文问题解决 问题描述&#xff1a; 长按TextField后&#xff0c;显示剪切、复制等选项为英文&#xff0c;如下图所示&#xff0c;这是因为问未设置语言本地化&#xff0c;我们需要进行设置。 首先在pubspec.yaml加入以下依赖…

rsyslog出现Unit rsyslog.service is masked不可用问题解决

博主在测试将日志发送到日志服务器的功能时遇到了rsyslog服务不可用的问题&#xff0c;具体来说&#xff0c;就是执行systemctl restart rsyslog或者 service rsyslog restart命令时&#xff0c;出现了标题中所述的Unit rsyslog.service is masked问题。网上查找了很多资料&…

【代码】平抑风电波动的电-氢混合储能容量优化配置(完美复现)matlab-yalmip-cplex/gurobi

程序名称&#xff1a;平抑风电波动的电-氢混合储能容量优化配置 实现平台&#xff1a;matlab-yalmip-cplex/gurobi 代码简介&#xff1a;针对电-氢混合系统协同平抑接入新型电力系统的 新能源波动问题&#xff0c;提出考虑碱性电解槽运行特性的电-氢 混合储能容量优化配置方案…

这一款 Mac 系统终端工具,已经用的爱不释手了!

&#x1f525;&#x1f525;&#x1f525;作为程序员或者运维管理人员&#xff0c;我们经常需要使用终端工具来进行服务器管理及各种操作&#xff0c;比如部署项目、调试代码、查看/优化服务、管理服务器等。 相信大家用的最多的终端工具就是 Xshell、iTerm2和Mobaxterm&#…

【JavaEE初阶】浅谈进程

✏️✏️✏️今天正式进入JavaEE初阶的学习&#xff0c;给大家分享一下关于进程的一些基础知识。了解这部分内容&#xff0c;只是为后续多线程编程打好基础&#xff0c;因此进程部分的知识&#xff0c;不需要了解更加细节的内容。 清风的CSDN博客 &#x1f61b;&#x1f61b;&a…

汽车电子 - UDS

汽车电子 - UDS 概念基本概念分类请求与响应寻址信息物理寻址功能寻址 协议格式&#xff1f;&#xff1f;&#xff1f;750/758厂家自定义的吗&#xff1f;&#xff1f;&#xff1f;&#xff0c; 所有的UDS服务都在这里边吗&#xff1f;&#xff1f;&#xff1f;&#xff0c;代码…