Qt——用于表格QTableView的模型

2023-11-18

如果想使用表格来呈现数据,Qt提供了一个方便的部件QTableWidget,但是直接用它实现一些功能可能比较困难。这里将介绍一种强大、灵活的方式来操作表格。

一、模型/视图架构

在这个架构中,模型用于存储数据,视图用于呈现数据,除此之外,还有一个称为委托的部分,委托显示视图中的每一项,并为可编辑的项提供合适的编辑器。

三者的关系如下图所示——

这篇博客只介绍模型/视图的部分,接下来用一个简单的例子来说明如何使用。

 

二、要实现的功能

以网易云音乐为例,它的部分搜索界面是这样的:

 

现在,我们依照网易云音乐做一个下面的窗口,并实现额外的一些功能。

 

要实现的功能:

1.网上搜索:从网上搜索歌曲的数据并呈现在左边的表格中;

2.本地搜索并选中:在左边的表格中进行搜索,选中与关键字相匹配的行;

3.本地搜索并过滤:在左边的表格中进行搜索,只显示与关键字相匹配的行,过滤隐藏不匹配的行。

 

三、联网搜索

1.准备工作

左边的表格使用 QTableView 。

为了存储数据,需要使用合适的模型,在这里我们使用 QStandardItemModel 。

同时为了实现过滤,需要另一个代理模型 QSortFilterProxyModel 。

//数据模型
class MusicInfoModel : public QStandardItemModel
{
public:
	void loadData(const QString &strKeyword);//用于加载网上搜索得到的数据
}
//主窗口
class MainWidget : public QWidget
{
	private slots:
	void searchOnlineSlot();			//网上搜索
	void searchAndSelcLocalSlot();      //本地搜索并选择
	void searchAndFilterLocalSlot();    //本地搜索并过滤
private:
	MusicInfoModel *m_pInfoModel;			//数据模型
	QSortFilterProxyModel *m_pFilterModel;	//过滤代理模型
}

  

以上只列出重要的成员变量和成员函数。

为了方便加载数据,我们将QStandardItemModel子类化,在子类中声明一个加载数据的函数 loadData 。

 

在主窗口的构造函数中初始化视图和模型——

m_pInfoModel = new MusicInfoModel(this);
m_pFilterModel = new QSortFilterProxyModel(this);
m_pFilterModel->setSourceModel(m_pInfoModel);
ui.musicInfoTblView->setModel(m_pFilterModel);

从上面可以看到,表格的视图模型是代理模型filterModel,而不是实际包含数据的模型infoModel。

 

2.加载数据

接下来网上搜索,获得数据并加载到表格中

首先定义歌曲信息的数据结构

//歌曲信息的数据结构
struct SongInfo
{
public:
	QString strName;	//歌曲标题
	QString strSinger;	//歌手名字
	QString strAlbum;	//专辑名称
};

完成数据模型中加载数据的函数:

void MusicInfoModel::loadData(const QString &strKeyword)
{
	QList<SongInfo> listSongInfo;	//歌曲信息的list

	//...省略的步骤
	//根据关键字strKeyword从网上搜索
	//并将搜索结果存储到listSongInfo中

	//清除数据模型中之前存在的数据,并重新设置表头(因为clear会把表头也清除掉)
	clear();
	setHorizontalHeaderLabels(QStringList() << QString::fromLocal8Bit("音乐标题") << QString::fromLocal8Bit("歌手") << QString::fromLocal8Bit("专辑"));
	//遍历list,将数据存在表中
	for (SongInfo songItem : listSongInfo)
	{
		QList<QStandardItem *> listItems;
		QStandardItem *pTitle = new QStandardItem(songItem.strName);
		QStandardItem *pSinger = new QStandardItem(songItem.strSinger);
		QStandardItem *pAlbum = new QStandardItem(songItem.strAlbum);
		listItems << pTitle << pSinger << pAlbum;
		appendRow(listItems);//加载一行数据
	}
}

 

注意:表中的每一项是一个QStandardItem,在加载一行之前,需要先把他们存储在一个QList中,然后调用appendRow函数,一次完成加载3列。

接下来,我们在主界面中调用数据模型对象的loadData函数,即可将数据全部填到表格中。

 

四、本地搜索并过滤

过滤很简单,只需要使用QSortFilterProxyModel中的相关函数。

void MainWidget::searchAndFilterLocalSlot()
{
	QString strKeyword = ui.textEdit->text();
	m_pFilterModel->setFilterFixedString(strKeyword);//根据字符串过滤
}

一些有用的函数:

 void setFilterKeyColumn(int column) :设置根据表的哪一列进行过滤,默认值为0,如果设置成-1,则会根据所有列进行搜索。

 setFilterFixedString(const QString &) :根据固定的字符串进行过滤。

 setFilterRegExp(const QRegExp &) :根据正则表达式进行过滤。

 

五、本地搜索并选中

void MainWidget::searchAndSelcLocalSlot()
{
	QItemSelection selection;
	int iFirstSelcRow = -1;
	for (int i = 0; i < m_pFilterModel->rowCount(); ++i)
	{
		//获得每一行的歌名、歌手名、专辑名
		QModelIndex songIndex = m_pFilterModel->index(i, 0);
		QModelIndex singerIndex = m_pFilterModel->index(i, 1);
		QModelIndex albumnIndex = m_pFilterModel->index(i, 2);
		QString strSong = m_pFilterModel->data(songIndex).toString();
		QString strSinger = m_pFilterModel->data(singerIndex).toString();
		QString strAlbumn = m_pFilterModel->data(albumnIndex).toString();
		//判断是否符合条件
		if (strSong.contains(strKeyword) || strSinger.contains(strKeyword) || strAlbumn.contains(strKeyword))
		{
			if (iFirstSelcRow == -1)
			{
				iFirstSelcRow = i;
			}
			//增加选中项
			QItemSelection rowSelc(songIndex, songIndex);
			selection.merge(rowSelc, QItemSelectionModel::Select);
		}
	}
	//清除之前所有选中项,并选中现在的所有匹配项
	QItemSelectionModel *pSelcModel = ui.musicInfoTblView->selectionModel();
	pSelcModel->clearSelection();
	pSelcModel->select(selection, QItemSelectionModel::Rows | QItemSelectionModel::Select);
	//视图滚动到第一个选中项的位置
	if (iFirstSelcRow != -1)
	{
		ui.musicInfoTblView->scrollTo(m_pFilterModel->index(iFirstSelcRow, 0));
	}
}

最终的简陋窗口:

 

以上只是视图/模型的使用作简单介绍,更多用法还请在实践中自行查找官方文档。

 

转载于:https://www.cnblogs.com/hellovenus/p/qt_table_model.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt——用于表格QTableView的模型 的相关文章

  • web移动端布局的那些事儿

    原文地址 github com HuJiaoHJ bl web移动端布局范畴很广 其中比较基础的几个话题 移动端适配 1px border 基础布局 本文主要分享这三个话题 一 移动端适配 提起移动端适配 大家想到的肯定是rem flexi
  • (ps2019)Photoshop 2019 最新破解版下载

    Photoshop CC 2019新增功能 下载地址点我 新功能介绍 https helpx adobe com cn photoshop using whats new html 经过改良设计的内容识别填充 借助 Adobe Sensei
  • 链表面试题(一):反转链表的算法实现

    关于链表的考察 链表是面试里面经常涉及到的考点 因为链表的结构相比于Hashmap Hashtable Concurrenthashmap或者图等数据结构简单许多 对于后者更多面试的侧重点在于其底层实现 比如Hashmap中Entry
  • 算法问题实战策略

    算法问题实战策略 基本信息作者 韩 具宗万 译者 崔盛一出版社 人民邮电出版社ISBN 9787115384621上架时间 2015 2 4出版日期 2015 年3月开本 16开页码 738版次 1 1 内容简介 算法问题实战策略 本书收录
  • Photoshop、Illustrator、Sketch哪个更好

    以前在交流组经常能看到大家争论哪个设计软件好 到底是你的吗 Illustrator好还是我的CorelDRAW或者他的Photoshop强大 但是跟着UI流行的设计 Sketch软件也加入了争论 让我们和你分享一下这篇文章 让我们来看看平面
  • 机器学习算法GBDT的面试要点总结-上篇

    1 简介 gbdt全称梯度提升决策树 在传统机器学习算法里面是对真实分布拟合的最好的几种算法之一 在前几年深度学习还没有大行其道之前 gbdt在各种竞赛是大放异彩 原因大概有几个 一是效果确实挺不错 二是即可以用于分类也可以用于回归 三是可
  • Linux下进程退出的几种形式

    进程退出 Linux 下进程的退出分为正常退出和异常退出两种 1 正常退出 a 在main 函数中执行return b 调用exit 函数 c 调用 exit 函数 2 异常退出 a 调用about函数 b 进程收到某个信号 而该信号使程序
  • Unity中UI框架的使用1-添加面板、显示Loading页面

    其中BasePanel和Canvas都是挂在面板的预制物上的 1 导入我们的UI框架 本篇文章中有用的是两个UIPanelType NUIManager和NBasePanel 会放在文章最后供大家使用 2 先将我们做好的Panel设置成预制
  • 一个互联网研发团队的标准配置

    做一件大事 通常会产生一个组织 对于一个组织来说 确定了梦想和目标之后 首要的事情是 组织分工和明确 权责 权利和责任分不清楚 效率必定低下 读书阶段的时候 无论是学习 还是做事 从来没有深刻地感受过 事倍功半 和 事半功倍 工作之后 经历
  • 二叉树结构的建立与遍历

    实验项目 1 编写建立二叉树的二叉链表存储结构 左右链表示 的程序 并以适当的形式显示和保存二叉树 2 完成二叉树的7种遍历操作 3 给定一个二叉树 编写算法完成下列应用 1 判断其是否为完全二叉树 2 求二叉树中任意两个结点的公共祖先 输
  • 雪糕的最大数量 排序+贪心

    雪糕的最大数量 雪糕的最大数量 题目描述 样例 数据范围 思路 代码 题目描述 夏日炎炎 小男孩 Tony 想买一些雪糕消消暑 商店中新到 n 支雪糕 用长度为 n 的数组 costs 表示雪糕的定价 其中 costs i 表示第 i 支雪
  • Leetcode2661. 找出叠涂元素

    Every day a Leetcode 题目来源 2661 找出叠涂元素 解法1 哈希 题目很绕 理解题意后就很简单 由于矩阵 mat 中每一个元素都不同 并且都在数组 arr 中 所以首先我们用一个哈希表 hash 来存储 mat 中每
  • WPF应用实战开发指南 - 如何实现动态内容展示

    在我们开发一些复杂信息的时候 由于需要动态展示一些相关信息 因此我们需要考虑一些控件内容的动态展示 可以通过动态构建控件的方式进行显示 如动态选项卡展示不同的信息 或者动态展示一个自定义控件的内容等等 目的就是能够减少一些硬编码的处理方式
  • Axure RP 8 for Mac/win中文版:打造完美交互式原型设计体验

    Axure RP 8 一款引领潮流的交互式原型设计工具 为设计师提供了无限的可能性 让他们能够创造出逼真的原型 从而更好地展示和测试他们的设计 Axure RP 8拥有丰富的功能和工具 让设计师可以轻松地创建出复杂的交互式原型 从简单的按钮
  • 独立搭建UI自动化测试框架分享

    今天给大家分享一个selenium testng maven ant的UI自动化 可以用于功能测试 也可按复杂的业务流程编写测试用例 今天此篇文章不过多讲解如何实现CI CD 只讲解自己能独立搭建UI框架 如果有其他好的框架也可以联系我 分
  • element ui backTop源码解析-逐行逐析

    backTop 回到顶部 组件简介 基础概念 返回页面顶部的操作按钮 代码
  • element ui弹窗在别的弹窗下方,优先级不高的问题

    在 弹窗 的标签中加入append to body即可解决该问题
  • 按照层次遍历结果打印完全二叉树

    按照层次遍历结果打印完全二叉树 按照推论结果 l 层首个节点位置 2 h l 1 l 层节点间距 2 h l 1 1 编码实现 public static
  • 从源码角度来谈谈 HashMap

    HashMap的知识点可以说在面试中经常被问到 是Java中比较常见的一种数据结构 所以这一篇就通过源码来深入理解下HashMap 1 HashMap的底层是如何实现的 基于JDK8 1 1 HashMap的类结构和成员 HashMap继承
  • 界面控件DevExpress WPF属性网格 - 让应用轻松显示编辑各种属性事件

    DevExpress WPF Property Grid 属性网格 灵感来自于Visual Studio Visual Studio启发的属性窗口 对象检查器 让在WPF应用程序显示和编辑任何对象的属性和事件变得更容易 P S DevExp

随机推荐

  • LVM条带卷

    4 4 2 创建条带卷 如果有大量连续读 写操作 创建条带逻辑卷可提高数据 I O 的效率 有关条带卷的常规信息 请查看 第 2 3 2 节 条带逻辑卷 创建条带逻辑卷时 可使用 lvcreate 命令的 i 参数指定条带数 这样就决定了逻
  • 数据库中delete和drop的区别

    delete 作用于数据上 即对数据进行删除 不修改表结构 例 delete from STU where sno S001 表示从学生表中删除学号为S001的学生 此过程并不破坏表结构 drop 可对数据库 表以及字段进行修改 操作涉及修
  • Linux·进程权限控制

    Linux系统的安全性得益于其进程权限和文件权限的控制机制 今天抽空梳理下Linux下的进程权限控制相关的文件权限涉及一点 首先明确四个名词 真实用户ID real ID 有效用户ID effective ID 保存用户ID Saved I
  • list泛型总结 Map<String, Collection<?>> result = new HashMap<>(6);集合list1 instanceof Collection

    package com gang import java util public class Harbor007 public static void main String args Calendar calendar Calendar
  • 查看python已安装模块的方法小结

    随着使用python的时间越来越长 安装的python模块也越来越多 时间久了都不记得自己之前到底对自己的电脑做过些什么了 于是乎就想要查看一下自己安装的python模块 现将查看方法总结如下 一 命令行下使用pydoc命令 在命令行下运行
  • 2023年人工智能GPT-4时代,最新13个ChatGPT商业市场AIGC应用正在掀起革命性变革!

    目录 前言 ChatGPT商业应用 LLM是星辰大海 1 研究背景 1 1 研究背景 1 2 研究方法 2 商业应用和案例分析 2 1 工具层 ChatGPT 搜索 ChatGPT 办公 ChatGPT 教育 2 2 行业层 ChatGPT
  • Pyramid Vision Transformer: A Versatile Backbone for Dense Prediction without Convolutions

    A 问题 首先 对于dense prediction tasks 完全无卷积的的transformer backbone少有人研究 而VIT作为用在图像分类任务的完全transformer结构 很难直接应用于像素级别的dense predi
  • JAVA中io流常见异常_javaAPI_IO流基础_异常

    异常 1 异常的概述和分类 java中的异常有一个超类Throwable 然后其有俩个子类接口Error和Exception 其中Error是严重问题 这一个是程序中无法解决的 而另一个 Exception则是一般问题 Exception又
  • Android 模拟器打开错误 :x86 emulation currently requires hardware acceleration!

    第一次配置完成 Android 下载 模拟器进行打开使用时 发生错误 x86 emulation currently requires hardware acceleration 如图所示 问题分析 x86 emulation 仿真器 模拟
  • Vue之监听属性

    一 什么是监听属性 监听属性是Vue js提供的一种用来监听和响应Vue实例中的数据变化的方式 在监听数据对象中的属性时 每当监听的属性发生变化 都会执行特定的操作 监听属性可以定义在watch选项中 也可以使用实例方法vm watch 在
  • C++变量声明定义

    1 extern 声明变量 在一个文件里声明以后 表示该变量要去其它文件找变量 告诉编译器 你现在编译的文件中 有一个标识符虽然没有在本文件或本文件当前位置中定义 但是它是在别的文件中或本文件其它位置定义的全局变量 你要放行 声明变量 ex
  • word中行距设置固定值,图片显示不全的问题

    撰写毕业大论文时 要求正文行间距设置为20磅固定值 但会出现 粘贴图片时 图片显示不全 软件也把图片做一行的固定值显示 解决办法是 选中图片 按ctrl 1单倍行距组合键 此时图片就能显示全了 图片的行间距就是单倍行距
  • 腾讯采用Intertrust的Marlin DRM方案保护其在线视频服务

    转自 http tech ifeng com internet detail 2013 01 11 21094087 0 shtml 1月10日 Intertrust公司今天宣布 已授权腾讯使用Marlin DRM方案保护腾讯在线视频平台的
  • 5.DML语句

    DML语句用于操作数据表的数据 如 插入 修改 删除 insert into update和delete from三个命令组成 1 insert into INSERT INTO grade id math VALUES 1 83 若省略表
  • Android下设置CPU核心数和频率

    现在的Android手机双核 四核变得非常普遍 同时CPU频率经常轻松上2G 功耗肯定会显著增加 而大多数的ARM架构的CPU采用的是对称多处理 SMP 的方式处理多CPU 这就意味着每个CPU核心是被平等对待的 同时打开又同时关闭 显然
  • python中的eval

    eval将字符串作为执行命令 题目 https www hackerrank com challenges py set discard remove pop 也可以使用getattr a b 相当于a b 代码如下 n int input
  • vue中如何监听localStorage中值的变化

    一 说明 在日常开发中 我们经常使用localStorage来存储一些变量 这些变量会存储在浏览中 对于localStorage来说 即使关闭浏览器 这些变量依然存储着 方便我们开发的时候在别的地方使用 二 localStorage的使用
  • Java集合的使用

    集合的使用 集合框架的概述 数组在存储多个数据的特点 数组在存储多个数据的缺点 Java 集合可分为 Collection 和 Map 两种体系 Collection接口 Map接口 Collection 接口的使用 说明 常用方法 案例一
  • java hashcode() 和equals()详解 以及set不能重复问题

    1 首先equals 和hashcode 这两个方法都是从object类中继承过来的 equals 方法在object类中定义如下 public boolean equals Object obj return this obj 很明显是对
  • Qt——用于表格QTableView的模型

    如果想使用表格来呈现数据 Qt提供了一个方便的部件QTableWidget 但是直接用它实现一些功能可能比较困难 这里将介绍一种强大 灵活的方式来操作表格 一 模型 视图架构 在这个架构中 模型用于存储数据 视图用于呈现数据 除此之外 还有