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的模型 的相关文章

  • Qt 不规则窗口,不规则按钮,不规划控件 不规则界面

    有一些特殊情况 需要使用不规则窗口或按钮 看起来非常炫酷 类似 Qt 实现 不规则样式设置 不是视觉欺骗 是真正的不规则 点击外面不会触发按钮的点击信号 Part1 不规则窗口 效果 显示成一张图片中的图形 使用带有透明区域的png图片 i
  • Consul服务注册与发现

    目录 一 Consul简介 一 官网 二 特点 二 安装并运行Consul 一 官网安装说明 二 下载 三 使用开发模式启动 三 服务提供者 四 服务消费者 五 三个注册中心异同点 一 CAP理论 二 AP架构 三 CP架构 一 Consu
  • Unique Binary Search Trees -- LeetCode

    原题链接 http oj leetcode com problems unique binary search trees 这道题要求可行的二叉查找树的数量 其实二叉查找树可以任意取根 只要满足中序遍历有序的要求就可以 从处理子问题的角度来
  • 堆栈01--用两个栈实现队列

    堆栈01 用两个栈实现队列 jz05 题目概述 解析 参考答案 注意事项 说明 题目概述 算法说明 用两个栈来实现一个队列 完成队列的Push和Pop操作 队列中的元素为int类型 测试用例 队列先进先出 输入 1 2 输出 1 2 解析
  • 算法问题实战策略

    算法问题实战策略 基本信息作者 韩 具宗万 译者 崔盛一出版社 人民邮电出版社ISBN 9787115384621上架时间 2015 2 4出版日期 2015 年3月开本 16开页码 738版次 1 1 内容简介 算法问题实战策略 本书收录
  • 用指针访问一维数组

    文章目录 顺序查找 数组方式实现 指针实现方式 对一位数组元素的访问有三种方式 指针变量的关系运算 引例 数组实现方式 主函数 指针实现方式 主函数 一维数组作为函数的参数 实际应用 顺序查找 要求用指针实现 在整数集合r中顺序查找与给定值
  • Qt 信号与槽

    Qt 信号与槽 在这章节里 我们学习 Qt 的信号与槽 这里分一个章节来学习这个 Qt 的信号与槽 可见 这个信号与槽有多么重要 在学习 Qt 的过程中 信号与槽是必不可少的部分 也是 Qt 编程的 基础 是 Qt 编程的一大创新 其实与
  • Unity中UI框架的使用1-添加面板、显示Loading页面

    其中BasePanel和Canvas都是挂在面板的预制物上的 1 导入我们的UI框架 本篇文章中有用的是两个UIPanelType NUIManager和NBasePanel 会放在文章最后供大家使用 2 先将我们做好的Panel设置成预制
  • Android4.0 SDK功能详解

    我在eoe的论坛找到的 就复制过来了 跟大家分享一下 Android 4 0 平台API等级 14 Android 4 0 是一次重要的平台发布版 为用户和应用程序开发者增加了大量的新特性 在下面我们将讨论的所有新特性和API中 因为它将
  • 基于Selenium和python的UI自动化测试方案

    一 概述 对于比较复杂的系统 每次有小的迭代测试同学不可能会把所有的流程验证一遍 如果开发无意改动影响了某些流程而测试又没测试到 就可能会出现生产问题 因此很有必要通过自动化的测试去确保系统的稳定性 自动化测试可以选择接口自动化测试和UI自
  • vue element-ui el-tooltip组件失效问题

    引用自 https blog csdn net ygrhlh article details 121660806 vue element ui el tooltip组件失效问题 因为公司项目年代久远以及谷歌chrome 80 后的sames
  • 【数据结构】双链表的定义和操作

    目录 1 双链表的定义 2 双链表的创建和初始化 3 双链表的插入节点操作 4 双链表的删除节点操作 5 双链表的查找节点操作 6 双链表的更新节点操作 7 完整代码 嗨 我是 Filotimo 很高兴与大家相识 希望我的博客能对你有所帮助
  • 【自动化测试】selenium元素定位方式大全!

    前言 当我们在使用selenium进行自动化测试工作时 元素定位是非常重要的一环 因为我们是借助脚本模拟我们通过鼠标和键盘对元素进行点击 输入内容和滑动操作的 所以准确的元素定位是我们执行测试脚本的重要一环 本文就来给大家介绍一下selen
  • app测试必掌握的核心测试:UI、功能测试!

    一 UI测试 UI即User Interface 用户界面 的简称 UI 设计则是指对软件的人机交互 操作逻辑 界面美观的整体设计 好的UI设计不仅是让软件变得有个性有品味 还要让软件的操作变得舒适 简单 自由 充分体现软件的定位和特点 手
  • 独立搭建UI自动化测试框架分享

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

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

    在 弹窗 的标签中加入append to body即可解决该问题
  • 创意无限,绘图轻松——Sketch for Mac矢量绘图软件全面介绍

    在现代设计领域 矢量绘图软件是设计师们必不可少的工具之一 而在众多矢量绘图软件中 Sketch for Mac凭借其强大的功能和友好的用户界面脱颖而出 成为众多设计师的首选 Sketch for Mac是一款专为Mac用户开发的矢量绘图软件
  • 从源码角度来谈谈 HashMap

    HashMap的知识点可以说在面试中经常被问到 是Java中比较常见的一种数据结构 所以这一篇就通过源码来深入理解下HashMap 1 HashMap的底层是如何实现的 基于JDK8 1 1 HashMap的类结构和成员 HashMap继承
  • 排序:计数排序

    一 概念 计数排序是非比较排序 是对哈希直接定址法的变形应用 二 思想 利用数组统计相同数据出现的次数 例如整型数据m出现n次 就在数组m位置记录数据为n 最后从头遍历数组打印数据即可 通俗来讲就是 数组下标即为数据 下标所指位置的值即为数

随机推荐

  • 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 但是直接用它实现一些功能可能比较困难 这里将介绍一种强大 灵活的方式来操作表格 一 模型 视图架构 在这个架构中 模型用于存储数据 视图用于呈现数据 除此之外 还有