Qt新手入门指南 - 如何创建模型/视图(三)
每个UI开发人员都应该了解ModelView编程,本教程的目标是为大家提供一个简单易懂的介绍。
Qt 是目前最先进、最完整的跨平台C++开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今,Qt已被运用于超过70个行业、数千家企业,支持数百万设备及应用。
在上文中,我们主要为大家介绍了Model/View(模型/视图)的一些基本概念(点击这里回顾>>),本文将继续为大家介绍如何创建一个简单的模型/视图应用。
点击获取Qt Widget组件下载(Q技术交流:166830288)
2. 一个简单的模型/视图应用
如果想开发一个模型/视图应用程序,应该从哪里开始呢?我们建议从一个简单的示例开始,逐步扩展它,这使得理解体系结构更加容易。对于许多开发人员来说,在调用IDE之前试图详细理解模型/视图体系结构是不太方便的,从具有演示数据的简单模型/视图应用程序开始实际上更容易。
下面是7个非常简单且独立的应用程序,它们展示了模型/视图编程的不同方面,源代码可以在examples/widgets/tutorials/modelview目录中找到。
2.3 表单元格内的时钟

我们仍然有一个只读表,但这一次内容每秒都在变化,因为正在显示当前时间。
(文件来源:examples/widgets/tutorials/modelview/3_changingmodel/mymodel.cpp)
QVariant MyModel::data(const QModelIndex &index, int role) const
{
int row = index.row();
int col = index.column();if (role == Qt::DisplayRole && row == 0 && col == 0)
return QTime::currentTime().toString();return QVariant();
}时钟的滴答声缺少了一些东西,需要每一秒都告诉视图时间已经改变、需要再次读取。我们用定时器来做这个,在构造函数中,我们将其间隔设置为1秒,并连接其超时信号。
(文件来源:examples/widgets/tutorials/modelview/3_changingmodel/mymodel.cpp)
MyModel::MyModel(QObject *parent)
: QAbstractTableModel(parent)
, timer(new QTimer(this))
{
timer->setInterval(1000);
connect(timer, &QTimer::timeout , this, &MyModel::timerHit);
timer->start();
}这里是对应的槽位:
(文件来源:examples/widgets/tutorials/modelview/3_changingmodel/mymodel.cpp)
void MyModel::timerHit()
{
// we identify the top left cell
QModelIndex topLeft = createIndex(0,0);
// emit a signal to make the view reread identified data
emit dataChanged(topLeft, topLeft, {Qt::DisplayRole});
}
通过发出dataChanged() 信号,我们要求视图再次读取左上角单元格中的数据。注意,没有显式地将dataChanged()信号连接到视图,这在调用setModel()时自动发生。
2.4 设置列和行标题
标题可以通过一个视图方法隐藏:ableView->verticalHeader()->hide();

然而,头部内容是通过模型设置的,所以我们重新实现headerData()方法:
(文件来源:examples/widgets/tutorials/modelview/4_headers/mymodel.cpp)
QVariant MyModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
switch (section) {
case 0:
return QString("first");
case 1:
return QString("second");
case 2:
return QString("third");
}
}
return QVariant();
}注意,方法headerData()也有一个参数role,其含义与MyModel::data()中的相同。
2.5 最小编辑示例
在本例中,我们将构建一个应用程序,通过重复输入到表格单元格中的值,自动用内容填充窗口标题。为了能够方便地访问窗口标题,我们将QTableView放在QMainWindow中。
模型决定编辑功能是否可用,为了启用可用的编辑功能,我们只需要修改模型,这是通过重新实现以下虚拟方法来实现的:setData() 和flags()。
(文件来源:examples/widgets/tutorials/modelview/5_edit/mymodel.h)
// mymodel.h
#include <QAbstractTableModel>
#include <QString>const int COLS= 3;
const int ROWS= 2;class MyModel : public QAbstractTableModel
{
Q_OBJECT
public:
MyModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
private:
QString m_gridData[ROWS][COLS]; //holds text entered into QTableView
signals:
void editCompleted(const QString &);
};我们使用二维数组QString m_gridData来存储数据,这使得m_gridData成为MyModel的核心。MyModel的其余部分就像一个包装器,并将m_gridData适配到QAbstractItemModel接口,同时我们引入了editCompleted()信号,这使得将修改后的文本传输到窗口标题成为可能。
(文件来源:examples/widgets/tutorials/modelview/5_edit/mymodel.cpp)
bool MyModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (role == Qt::EditRole) {
if (!checkIndex(index))
return false;
//save value from editor to member m_gridData
m_gridData[index.row()][index.column()] = value.toString();
//for presentation purposes only: build and emit a joined string
QString result;
for (int row = 0; row < ROWS; row++) {
for (int col= 0; col < COLS; col++)
result += m_gridData[row][col] + ' ';
}
emit editCompleted(result);
return true;
}
return false;
}每次用户编辑单元格时都会调用setData(),index参数告诉我们编辑了哪个字段,value提供了编辑过程的结果。角色总是被设置为Qt::EditRole ,因为我们的单元格只包含文本,如果存在一个复选框,并且用户权限设置为允许选择该复选框,则调用也会将角色设置为Qt::CheckStateRole。
(文件来源:examples/widgets/tutorials/modelview/5_edit/mymodel.cpp)
Qt::ItemFlags MyModel::flags(const QModelIndex &index) const
{
return Qt::ItemIsEditable | QAbstractTableModel::flags(index);
}可以使用flags()调整单元格的各种属性。
返回Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled足以向编辑器显示一个单元格可以被选择。
如果编辑一个单元格修改的数据多于该特定单元格中的数据,则模型必须发出dataChanged()信号,以便读取已更改的数据。
相关文章:
 
Qt新手入门指南 - 如何创建模型/视图(三)
每个UI开发人员都应该了解ModelView编程,本教程的目标是为大家提供一个简单易懂的介绍。Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今ÿ…...
 
【Spring】手动实现简易AOP和IOC
前言 XML:通过Dom4j对XML进行解析和验证。 IOC:通过获取要创建对象的Class类型、构造函数后,通过反射来实现。 AOP:通过使用JDK动态代理和Cglib动态代理实现。 一、解析XML 1.1、解析bean标签 /*** 解析bean标签* param xmlBean…...
 
EasyExcel的使用
这里写目录标题先导入依赖最简单的写最简单的读項目开发中的一些操作xml一定要默認放先导入依赖 <dependencies><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.7</version><…...
 
基础篇(-1)-java特点、JDK、JRE、JVM区别、字节码编译、跨平台、程序运行
文章目录1.Java的特点有哪些?2.JDK和JRE和JVM的区别3.Java为什么采用字节码编译?4.什么是跨平台?5.Java程序从源代码到运行需要三步?1.Java的特点有哪些? Java是一种编程语言,被特意设计用于互联网的分布式…...
 
【网络编程】Java快速上手InetAddress类
概念 Java具有较好的网络编程模型/库,其中非常重要的一个API便是InetAddress。在Java.net 网络编程中中有许多类都使用到了InetAddress 这个类代表一个互联网协议(IP)地址。 IP地址是一个32(IPV4)位或128(…...
 
小小bat-day1-自动文件上传
前言:日常服务器备份文件或者生产设备等数据文件都统一保存至文件服务器,进行日志分析或者将生产文件CSV、图片等转存至数仓进行数据分析,尤其生产的部分数据是保存在个人电脑的PC端,数据杂,获取困难,手动整…...
2023年美赛D题公布
问题D:联合国可持续发展目标的优先次序背景联合国制定了17项可持续发展目标(SDGs)。实现这些目标最终会改善世界各地许多人的生活。这些目标并不是相互独立的。所以,在某些目标上的积极收获通常是有影响的(积极的或消极的,有时两者都有)。这种相互联系使…...
 
Gartner 再度预测2023低代码趋势,真的会赚钱吗?
2023年,从业者对低代码的发展充满了想象,人们认为,未来低代码的商业价值不可估量。 此话并非空穴来风。据Gartner的最新报告显示,到2023年,超过70%的企业将采用低代码作为他们发展战略的关键目标之一;到202…...
 
Zebra ZT410 ZT411 导入中文字体
1.设置--发送到打印机 2.字体--添加--下载 --windows 字体库下载到zebra 打印机 3.字体--工具--调用 ZEBRA驱动包中驱动。 4.老版打印机导入方式 Zebra ZPL条形码打印机上如何下载和使用TrueType或External字体-敏用数码(上海北京济南洛阳)|专注于条码数据处理 (chongshang.co…...
 
nextTick 的使用和原理(面试题)
答题思路: nextTick 是做什么的?为什么需要它?开发时什么时候使用?介绍一下如何使用nextTick原理解读,结合异步更新和nextTick生效方式 1. nextTick是做什么的? nextTick是等待下一次DOM更新刷新的工具方法…...
Hudi系列19:Hudi写入模式
一. Changelog 模式 如果希望 Hoodie 保留消息的所有变更(I/-U/U/D), 之后接上 Flink 引擎的有状态计算实现全链路近实时数仓(增量计算), Hoodie 的 MOR 表通过行存 原生支持 保留消息的所有变更(format 层面的集成), 通过流读MOR 表可以消费到所有的变…...
 
Kubernetes安全
Kubernetes RBAC授权 Kubernetes 安全框架 K8S安全控制框架主要由下面3个阶段进行控制,每一个阶段都支持插件方式,通过API Server配置来启用插件。1. Authentication(鉴权) K8s Apiserver提供三种客户端身份认证:• H…...
 
全国进入裁员潮,到底是大厂难混?还是我技不如人?
前言 面对裁员,每个人的心态不同。他们有的完全没有料想到自己会被裁,有的却对裁员之事早有准备。大多数人,我想是焦虑失落的吧。 01 “降本增效”,HR怒提裁员刀 小默 | 32岁 芯片行业 人力资源 1月份,身处芯片行业H…...
 
电子技术——内部电容效应以及MOS与BJT的高频响应模型
电子技术——内部电容效应以及MOS与BJT的高频响应模型 耦合和旁路电容决定了放大器的低频响应,同时内部电容效应决定了放大器的高频响应。本节,我们简单简单介绍一下内部电容效应,并且更重要的是如何在小信号模型中模型化内部电容效应。 MOS…...
华为OD机试题 - 出租车计费(JavaScript)
最近更新的博客 2023新华为OD机试题 - 斗地主(JavaScript)2023新华为OD机试题 - 箱子之形摆放(JavaScript)2023新华为OD机试题 - 考古学家(JavaScript)2023新华为OD机试题 - 相同数字的积木游戏 1(JavaScript)2023新华为OD机试题 - 最多等和不相交连续子序列(JavaScri…...
 
Django框架进阶版
一、Django介绍 1.起源 2005年发布,采用python语言编写的。 早期Django主要做新闻和内容管理 重量级python web框架,配备了大量组件 2.组件 包含组件如下 基本配置文件/路由系统 MTV设计模式 Cookies和Session 分页和发邮件 Admin管理后台 3…...
 
2023美赛F题全部代码+数据+结果 数学建模
2023年美赛F题全部思路 数据代码都已完成 全部内容见链接:https://www.jdmm.cc/file/2708700/ 1.根据文献选的GGDP的指标,发现GGDP与水资源等有关,由此可以筛选出影响GGDP的所有因子,并可以用所有因子利用层次分析法建立评价体…...
Java基础-logback日志使用
日志 1.1 作用:  跟输出语句一样,可以把程序在运行过程中的详细信息都打印在控制台上。  利用log日志还可以把这些详细信息保存到文件和数据库中。 1.2 使用步骤:  不是java的,也不是自己写的,是第三方提供…...
 
kaggle竞赛-宠物受欢迎程度(赛题讲解与数据分析)
比赛官网地址 赛题介绍 petfinder是马来西亚领先的动物福利平台宠物网站地址 该网站使用可爱指数来排名宠物照片。它分析了图片组成和其他因素,并与数千个宠物档案的表现进行了比较。 在这场比赛中,你将分析原始图像和元数据来预测宠物照片的“Pawp…...
 
Go语言基础知识学习笔记
环境准备 下载安装Golang:https://golang.google.cn/dl/ 因为国外下载速度较慢,我们需要配置国内代理 # 开启包管理工具 go env -w GO111MODULEon # 设置代理 go env -w GOPROXYhttps://goproxy.cn,direct # 设置不走 proxy 的私有仓库,多…...
 
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
 
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
 
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
 
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
 
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
 
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
 
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
