QT模型视图结构1

news2024/9/20 20:55:27

文章目录

  • Qt 模型视图结构概述(一)
    • 1、模型/视图结构基本原理
    • 2、模型
    • 3、视图
    • 4、代理
    • 5、简单实例

Qt 模型视图结构概述(一)

模型/视图结构是一种将数据存储界面展示分离的编程方法。模型存储数据,视图组件显示模型中的数据,在视图组件里修改的数据会被自动保存到模型里。模型的数据来源可以是内存中的字符串列表或二维表格型数据,也可以是数据库中的数据表,一种模型可以用不同的视图组件来显示数据,所以模型/视图结构是一种高效、灵活的编程结构。

1、模型/视图结构基本原理

GUI 程序的主要功能是可由用户在界面上编辑和修改数据,典型的如数据库应用程序。在数据库应用程序中,界面上的数据来源于数据库,用户在界面上修改数据,修改后的数据又保存到数据库。

​ 将界面与原始数据分离,又通过模型将界面和原始数据关联起来,从而实现界面与原始数据的交互操作,这是处理界面与数据的一种较好的方式。

​ Qt 使用模型/视图结构来处理这种关系,模型/视图的基本结构如图 1 所示,它包括以下几个部分。
在这里插入图片描述

图 1 模型/视图基本结构
  • 源数据(data)是原始数据,如数据库的一个数据表或 SQL查询结果、内存中的一个字符串列表或磁盘文件系统结构等。
  • 视图(view)也称为视图组件,是界面组件,视图从模型获得数据然后将其显示在界面上。Qt 提供一些常用的视图组件,如 QListViewQTreeViewQTableView 等。
  • 模型(model)也称为数据模型,与源数据通信,并为视图组件提供数据接口。它从源数据提取需要的数据,用于视图组件进行显示和编辑。Qt 中有一些预定义的模型类,如QStringListModel 是字符串列表的模型类,QSqlTableModel 是数据库中数据表的模型类。
  • 代理(delegate)在视图与模型之间交互操作时提供的临时编辑器。模型向视图提供数据是单向的,一般仅用于显示。当需要在视图上编辑数据时,代理会为编辑数据提供一个编辑器,这个编辑器获取模型的数据、接受用户编辑的数据后又将其提交给模型。例如在QTableView 组件上双击一个单元格来编辑数据时,在单元格里就会出现一个 QLineEdit 组件,这个编辑框就是代理提供的临时编辑器。
    由于通过模型/视图结构将源数据与显示和编辑界面分离,我们可以将一个模型在不同的视图中显示,也可以为一些特殊源数据设计自定义模型,或者在不修改模型的情况下设计特殊的视图组件。所以,模型/视图结构是一种高效、灵活的编程结构。
    模型、视图和代理使用信号和槽进行通信。当源数据发生变化时,模型发射信号通知视图组件;当用户在界面上操作数据时,视图组件发射信号表示操作信息;在编辑数据时,代理会发射信号告知模型和视图组件编辑器的状态。

2、模型

所有基于项(item)的模型类都是基于 QAbstractItemModel 类的,这个类定义了视图组件和代理存取数据的接口。模型只是在内存中临时存储数据,模型的数据来源可以是其他类、文件、数据库或任何数据源。

Qt 中几个主要的模型类的继承关系如图 2 所示。QAbstractItemModel 的父类是 QObject,所以模型类支持 Qt 的元对象系统。
在这里插入图片描述

图 2 模型类的继承关系

抽象模型类 QAbstractItemModel 不能直接用于创建实例对象,常用的几个模型类如表 1 所示。

表 1 常用的模型类
模型类功能
QFileSystemModel用于表示计算机上文件系统的模型类
QStringListModel用于表示字符串列表数据的模型类
QStandardItemModel标准的基于项的模型类,每个项是一个 QStandardItem 对象
QSqlQueryModel 用于表示数据库 SQL 查询结果的模型类
QSqlTableModel用于表示数据库的一个数据表的模型类

3、视图

视图就是用于显示模型中的数据的界面组件,Qt 提供的视图组件主要有以下几个。

表 2 常用的视图类
视图组件用于显示单列的列表数据,适用于一维数据的操作
QListView用于显示单列的列表数据,适用于一维数据的操作
QTreeView用于显示树状结构数据,适用于树状结构数据的操作
QTableView用于显示表格数据,适用于二维表格数据的操作
QColumnView用多个 QListView 显示树状结构数据,树状结构的一层用一个QListView显示
QUndoView用于显示 undo 指令栈内数据的视图组件,是 QListView 的子类

QListWidgetQTreeWidgetQTableWidget 这 3 个用于处理项数据的组件。这3 个类分别是 3 个视图类的子类,称为视图类的便利类(convenience class)。这些类的继承关系如图 3 所示。
在这里插入图片描述

图 3 视图类的继承关系

只需调用视图类的 setModel()函数为视图组件设置一个模型,模型的数据就可以显示在视图组件上。在视图组件上修改数据后,数据可以自动保存到模型里。视图组件的数据来源于模型,视图组件不存储数据。便利类则为组件的每个节点或单元格创建一个项,用项存储数据,例如对于 QTableWidget 类这个便利类,表格的每个单元格关联一个QTableWidgetItem 对象。便利类没有模型,它实际上是用项的方式替代了模型的功能,将界面与数据绑定。因此,便利类缺乏对大型数据源进行灵活处理的能力,只适用于小型数据的显示和编辑,而视图组件则会根据模型的数据内容自动显示,有助于减少编程工作量,使用起来也更灵活。

4、代理

代理就是在视图组件上为编辑数据提供的临时编辑器,例如在 QTableView 组件上编辑一个单元格的数据时,默认会提供一个 QLineEdit 编辑框。代理负责从模型获取相应的数据,然后将其显示在编辑器里,修改数据后又将编辑器里的数据保存到模型中。
QAbstractItemDelegate 是所有代理类的基类。它有两个子类, QItemDelegate 和QStyledItemDelegate ,这两个类的功能基本相同,而QStyledItemDelegate 能使用 Qt 样式表定义的当前样式绘制代理组件,所以,QStyledItemDelegate是视图组件使用的默认的代理类。
对于一些特殊的数据编辑需求,例如只允许输入整数时使用 QSpinBox 作为代理组件更合适,需要从列表中选择数据时则使用 QComboBox作为代理组件更好,这时就可以从 QStyledItemDelegate继承创建自定义代理类。

5、简单实例

展示了模型/视图类使用的简单实例 main.cpp


#include <QApplication>
#include <QSplitter>
#include <QFileSystemModel>
#include <QTreeView>
#include <QListView>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QSplitter *splitter = new QSplitter;
    QFileSystemModel *model = new QFileSystemModel;
    model->setRootPath(QDir::currentPath());
    QTreeView *tree = new QTreeView(splitter);
    tree->setModel(model);
    tree->setRootIndex(model->index(QDir::currentPath()));
    QListView *list = new QListView(splitter);
    list->setModel(model);
    list->setRootIndex(model->index(QDir::currentPath()));
    splitter->setWindowTitle("Two views onto the same file system model");
    splitter->show();
    
    return app.exec();
}

实例运行展示如下图
在这里插入图片描述

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

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

相关文章

QTreeView模糊查询

本文代码效果如下&#xff1a; 本文代码&#xff1a; https://download.csdn.net/download/Sakuya__/89759410https://download.csdn.net/download/Sakuya__/89759410 代码之路 MainWindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #incl…

【Linux取经之路】Linux项目自动化构建工具-make/makefile git三板斧

目录 关于make和makefile 一个案例 make和makefile的使用 makefile的基本语法 git的使用 关于make和makefile make是 Linux 系统中广泛使用的一个自动化构建工具&#xff0c;它根据用户定义的规则&#xff08;通常保存在一个名为 makefile的文件中&#xff09;来自动编译…

TikTok商家如何通过真人测评提高流量和销量?

在当今的社交媒体营销领域&#xff0c;TikTok&#xff08;抖音国际版&#xff09;以其独特的短视频内容和庞大的用户群体&#xff0c;成为了品牌营销和产品推广的热门平台。其中&#xff0c;真人测评作为一种有效的营销策略&#xff0c;正逐渐受到商家的青睐。本文将探讨TikTok…

医学数据分析实训 项目三 关联规则分析作业--在线购物车分析--痹症方剂用药规律分析

文章目录 项目三 关联规则分析一、实践目的二、实践平台三、实践内容任务一&#xff1a;在线购物车分析&#xff08;一&#xff09;数据读入&#xff08;二&#xff09;数据理解&#xff08;三&#xff09;数据预处理&#xff08;四&#xff09;生成频繁项集&#xff08;五&…

常见算法——自相关的含义及Python、C实现

常见算法——自相关的含义及C实现 一、概念1. 自相关概念2. 滞后期示例说明&#xff1a; 二、自相关的计算步骤&#xff1a;1. 确定滞后期 (Lag)&#xff1a;2. 计算平均值&#xff1a;3. 计算自相关&#xff1a; 三、示例 Python自相关计算1. 代码2. 运行结果 四、C语言实现自…

yjs06——numpy的介绍与优势(1)

1.numpy是什么&#xff1f; numpy是python的一个科学计算库&#xff0c;用于快速处理 任意维度的数据&#xff1b; numpy的存储单元/基本数据类型是 ndarray&#xff08;多维数组&#xff09; 2.多维数组的建立&#xff1a; import numpy as np np.array([ [1,2,3], [4,5,6…

C++ | Leetcode C++题解之第406题根据身高重建队列

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {sort(people.begin(), people.end(), [](const vector<int>& u, const vector<int>& v) …

IV 无规矩不成方圆,区块链的“规矩”是怎么起作用的?

大家好啊&#xff0c;我是豆小匠。 通过前面几期&#xff0c;我们知道区块链是一种非中心化的解决方案&#xff0c;没有“中央处理器”。 那么&#xff0c;区块链中的各种操作&#xff0c;比如转账、状态记录等规则是怎么定义&#xff0c;又是怎么起作用的呢&#xff1f; 本…

QT--connect的使用

在qt里面我们可以用connect将信号与槽函数连接器起来&#xff0c;而connect是一个常用的函数&#xff0c;用法也非常简单。 来看一个非常简单的栗子 Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);qpbnew QPushButton(this)…

go语言中的数组指针和指针数组的区别详解

1.介绍 大家知道C语言之所以强大&#xff0c;就是因为c语言支持指针&#xff0c;而且权限特别大&#xff0c;c语言可以对计算机中任何内存的指针进行操作&#xff0c;这样自然而然也会带来一些不安全的因素&#xff0c;所以在golang中&#xff0c;「取消了对指针的一些偏移&…

清理Go/Rust编译时产生的缓存

Go Mac 1T的磁盘频频空间高级&#xff0c;发现是/Users/yourname/Library/Caches/go-build 目录占用了大量空间。 此目录保存来自 Go 构建系统的缓存构建工件。 如果目录太大&#xff0c;请运行go clean -cache。 运行go clean -fuzzcache以删除模糊缓存。 当时直接手工清理了…

C++——多线程编程(从入门到放弃)

进程&#xff1a;运行中的程序 线程&#xff1a;进程中的进程 线程的最大数量取决于CPU的核心数 一、将两个函数添加到不同线程中 demo&#xff1a;两个函数test01()和test02()&#xff0c;实现将用户输入的参数进行打印输出1000次 将这两个函数均放到独立的线程t1和t2中&…

STM32 的 CAN 通讯全攻略

目录 一、CAN 通讯概述 二、 CAN 通讯原理 1.ISO11898 标准下的物理层特征 2.CAN 协议的帧类型 3. 总线仲裁介绍 4.位时序 5.STM32 CAN 控制器简介 6.标识符筛选器 三、软件设计 1.发送流程 1.1初始化 CAN 控制器 1.2准备发送数据 1.3 将数据填充到发送缓冲区 1.4…

初始c++的继承

概念&#xff1a; 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保持原有类特性的基础上进行扩展&#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称派生类。继承呈现了面向对象程序设计的层次结构&#xff0c…

Java高级Day43-类加载

117.类加载 静态和动态加载 反射机制是java实现动态语言的关键&#xff0c;也就是通过反射实现类动态加载 静态加载&#xff1a;编译时加载相关的类&#xff0c;如果没有则报错&#xff0c;依赖性太强 动态加载&#xff1a;运行时加载需要的类&#xff0c;如果运行时不用该类…

集群聊天服务器项目【C++】(五)网络模块和业务模块

经过前面介绍相关的库和工具&#xff0c;比如Json、CMake、muduo等&#xff0c;我们可以开始编写本项目的代码了。 1.项目目录创建 一般一个项目由以下结构组成&#xff1a; bin文件夹存放&#xff1a;可执行程序build文件夹存放&#xff1a;编译过程中的临时文件include文…

消失的数去哪里了

大家好&#xff0c;我是大圣&#xff0c;最近消失了很长一段时间了&#xff0c;之前答应粉丝要更新的文章也没有按时更新。其实我这段时间去闭关修炼去了&#xff0c;现在满血归来啦&#xff0c;之前答应粉丝的文章都会陆续发出来的。 消失的 Count 去哪了 今天给大家分享一个…

BolckingQueue

队列 队列的特点先进先出&#xff08;FIFO&#xff09;。 如图&#xff1a; 进入队列的顺序是1&#xff0c;2&#xff0c;3&#xff0c;那么出队列的顺序只能是1&#xff0c;2&#xff0c;3&#xff0c;不可能是其他顺序&#xff0c;这是由队列的特点保证的。 保存数据的基本…

彻底理解浅拷贝和深拷贝

目录 浅拷贝实现 深拷贝实现自己手写 浅拷贝 浅拷贝是指创建一个新对象&#xff0c;这个对象具有原对象属性的精确副本 基本数据类型&#xff08;如字符串、数字等&#xff09;&#xff0c;在浅拷贝过程中它们是通过值传递的&#xff0c;而不是引用传递&#xff0c;修改值并不…

基于yolov8的茶叶病害检测系统python源码+onnx模型+评估指标曲线+精美GUI界面

【算法介绍】 基于YOLOv8的茶叶病害检测系统&#xff0c;是利用深度学习技术&#xff0c;特别是YOLOv8这一先进的目标检测算法&#xff0c;来精准识别和监测茶叶生长过程中出现的各种病害。该系统通过无人机、地面机器人或固定摄像头等设备&#xff0c;定期采集茶园的高分辨率…