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.hqwc.cn/news/219339.html

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

相关文章

文件元数据批量修改:mp3音频和mp4视频的元数据如何批量修改

在数字媒体处理和管理的日常工作中&#xff0c;文件元数据的批量修改是一个常见的需求。元数据&#xff0c;或者称为文件信息&#xff0c;可以包括文件的创建日期、修改日期、文件名、文件大小、标签等。在音乐和视频处理领域&#xff0c;例如对mp3音频和mp4视频文件&#xff0…

R语言期末复习一

创建一个长度为7的字符向量&#xff0c;元素为"A", "B", "C", "D", "E", "F", "G"&#xff0c;并命名为vec1。 创建一个因子&#xff0c;包含6个水果&#xff1a;"apple", "banana"…

梯度详解与优化实战

什么是梯度 对所有自变量求偏微分构成的向量&#xff0c;它是一个向量&#xff08;有大小和函数值增长方向&#xff09; 导数是一个标量 找最小值点坐标的案例 import torchimport numpy as np import matplotlib.pyplot as plt def himmelblau(x):return (x[0]**2x[1]-11)…

android系统新特性——用户界面以及系统界面改进

用户界面改进 Android用户界面改进最明显的就是MD了。MD是Google于2014年推出的设计语言&#xff0c;它是一套完整的设计系统&#xff0c;包含了动画、样式、布局、组件等一系列与设计有关的元素。通过对这些行为的描述&#xff0c;让开发者设计出更符合目标的软件&#xff0c…

电子学会C/C++编程等级考试2023年03月(二级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:数字字符求和 请编写一个程序实现以下功能:从一个字符串中,提取出所有的数字字符即0-9,并作为数求和。 时间限制:1000 内存限制:65536输入 一行字符串,长度不超过100,字符串中不含空格。输出 字符串中所有数字字符作为数…

泛型你掌握多少?包装类你深入了解过吗?快进来看看吧~

目录 1、泛型是什么——引出泛型 2、泛型的使用 2.1、语法 2.2泛型类的使用 2.3、裸类型 3、泛型如何编译 3.1、擦除机制 3.2、为什么不能实例化泛型类型数组 4、泛型的上界 5、泛型方法 5.1、语法 5.2、举例 6、通配符 6.1、什么是通配符 6.2、统配符解决了什么…

【深入剖析K8s】容器技术基础(一):从进程开始说起

容器其实是一种特殊的进程而已。 可执行镜像 为了能够让这些代码正常运行’我们往往还要给它提供数据’比如我们这个加法程序所需要的输人文件这些数据加上代码本身的二进制文件放在磁盘上’就是我们平常所说的一个程序,也叫代码的可执行镜像&#xff08;executablejmage&…

机器学习:攻击方法FGSM系列

任务 FGSM I-FGSM MI-FGSM Ensemble Attack 攻击评价指标 准确率越低表明攻击越好 数据 预训练模型 BaseLine 实践

模块的学习

模块合包的基本概念&#xff1a; 模块&#xff08;module&#xff09;&#xff1a;在python中&#xff0c;xx.py文件&#xff0c;就可以被看作模块 包&#xff08;package&#xff09;: 用来管理和存放模块的文件夹&#xff0c;就被称为包&…

C语言从入门到精通之【表达式和语句】

1 表达式 表达式由运算符和运算对象组成&#xff0c;最简单的表达式一个单独的运算对象。每个表达式都有一个值&#xff0c;并且是根据运算符优先级规定的顺序来执行&#xff0c;以下是一些表达式&#xff1a; 4 -6 421 a*(b c/d)/20 q 5*2 x q % 3 #q > 3 2 语句 语句…

HCIP-十、BGP基础

十、BGP基础 实验拓扑实验需求及解法1.R1 属于 AS100&#xff0c;R2/3/4 属于 AS200&#xff0c;R5 属于 AS3002.AS200 内运行 OSPF3.建立 IBGP 邻居4.建立 EBGP 邻居5.BGP 发布路由6.路由黑洞 实验拓扑 实验需求及解法 本实验模拟 ISP 网络拓扑&#xff0c;运行 BGP。如图所示…

电子学会C/C++编程等级考试2022年09月(二级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:统计误差范围内的数 统计一个整数序列中与指定数字m误差范围小于等于X的数的个数。 时间限制:5000 内存限制:65536输入 输入包含三行: 第一行为N,表示整数序列的长度(N <= 100); 第二行为N个整数,整数之间以一个空格分…