【QT】Model/View结构

news2024/9/25 9:32:07

目录

1 概述

2 Mode/View基本原理

3 数据模型

4 视图组件

5 代理

6 Model/View结构的一些概念

6.1 Model/View的基本结构

6.2 模型索引

6.3 行号和列号

6.4 父项

6.5 项的角色

1 概述

        Model/View(模型/视图)结构是Qt中用界面组件显示与编辑数据的一种结构,视图(Mew)是显示和编辑数据的界面组件,模型(Model)是视图与原始数据之间的接口。Model/View结构的典型应用是在数据库应用程序中,例如数据库中的一个数据表可以在一个QTableView组件中显示和编辑。
        主要的视图组件有QListView、QTreeView和QTableView,QListWidget、QTreeWidget和QTableWidget分别是这3个类的便利类,它们不使用数据模型,而是将数据直接存储在组件的每个项里。

Mode/View基本原理

        GUI应用程序的一个很重要的功能是由用户在界面上编辑和修改数据,典型的如数据库应用程序。数据库应用程序中,用户在界面上执行各种操作,实际上是修改了界面组件所关联的数据库内的数据。
        将界面组件与所编辑的数据分离开来,又通过数据源的方式连接起来,是处理界面与数据的一种较好的方式。Qt使用Model/View结构来处理这种关系,Model/View的基本结构如图5-1所示。其中各部分的功能如下。
  • 数据(Data)是实际的数据,如数据库的一个数据表或SQL查询结果,内存中的一个StringList,或磁盘文件结构等。
  • 视图或视图组件(View)是屏幕上的界面组件,视图从数据模型获得每个数据项的模型索引(modelindex),通过模型索引获取数据,然后为界面组件提供显示数据。Qt提供一些现成的数据视图组件,如QListView、QTreeView和QTableView等。
  • 模型或数据模型(Model)与实际数据通信,并为视图组件提供数据接口。它从原始数据提取需要的内容,用于视图组件进行显示和编辑。Qt中有一些预定义的数据模型,如QStringListModel可作为StringList的数据模型,QSqlTableModel可以作为数据库中一个数据表的数据模型。
        由于数据源与显示界面通过Model/View结构分离开来,因此可以将一个数据模型在不同的视图中显示,也可以在不修改数据模型的情况下,设计特殊的视图组件。
        在Model/View结构中,还提供了代理(Delegate)功能,代理功能可以让用户定制数据的界面显示和编辑方式。在标准的视图组件中,代理功能显示一个数据,当数据被编辑时,代理通过模型索引与数据模型通信,并为编辑数据提供一个编辑器,一般是一个组件。
        模型、视图和代理之间使用信号和槽通信。当源数据发生变化时,数据模型发射信号通知视图组件;当用户在界面上操作数据时,视图组件发射信号表示这些操作信息;当编辑数据时,代理发射信号告知数据模型和视图组件编辑器的状态。

数据模型

        所有的基于项数据(itemdata)的数据模型(Model)都是基于QAbstractItemModel类的,这个类定义了视图组件和代理存取数据的接口。数据无需存储在数据模型里,数据可以是其他类、文件、数据库或任何数据源。Qt中与数据模型相关的几个主要的类的层次结构如图5-2所示。
        图5-2中的抽象类是不能直接使用的,需要由子类继承来实现一些纯虚函数。Qt提供了一些模型类用于项数据处理,常见的几个见表5-1。
        如果这些现有的模型类无法满足需求,用户可以从QAbstractItemModeI、QAbstractListModeI或QAbstractTabIeModeI继承,生成自己定制的数据模型类。

4 视图组件

      视图组件(View)就是显示数据模型的数据的界面组件,Qt提供的视图组件如下。
  • QListView:用于显示单列的列表数据,适用于一维数据的操作。
  • QTreeView:用于显示树状结构数据,适用于树状结构数据的操作。
  • QTableView:用于显示表格状数据,适用于二维表格型数据的操作。
  • QColumnView:用多个QListView显示树状层次结构,树状结构的一层用一个QListView显示。
  • QHeaderView:提供行表头或列表头的视图组件,如QTableView的行表头和列表头。
        视图组件在显示数据时,只需调用视图类的setModel()函数,为视图组件设置一个数据模型就可以实现视图组件与数据模型之间的关联,在视图组件上的修改将自动保存到关联的数据模型里,一个数据模型可以同时在多个视图组件里显示数据。
        QListWidget、QTreeWidget和QTableWidget是用于数据编辑的组件,这3个类称为便利类,分别是3个视图类的子类,其层次关系如图5-3所示。
        用于Model/View结构的几个视图类直接从QAbstractItemView继承而来,而便利类则从相应的视图类继承而来。
        视图组件类的数据采用单独的数据模型,视图组件不存储数据。便利类则为组件的每个节点或单元格创建一个项(item),用项存储数据、格式设置等。所以,便利类没有数据模型,它实际上是用项的方式集成了数据模型的功能,这样就将界面与数据绑定了。所以,便利类缺乏对大型数据源进行灵活处理的能力,适用于小型数据的显示和编辑。

5 代理

        代理(Delegate)就是在视图组件上为编辑数据提供编辑器,如在表格组件中编辑一个单元格的数据时,缺省是使用一个QLineEdit编辑框。代理负责从数据模型获取相应的数据,然后显示在编辑器里,修改数据后,又将其保存到数据模型中。
        QAbstractItemDelegate是所有代理类的基类,作为抽象类,它不能直接使用。它的一个子类
QStyledItemDelegate,是Qt的视图组件缺省使用的代理类。
        对于一些特殊的数据编辑需求,例如只允许输入整型数,使用一个QSpinBox作为代理组件
更恰当,从列表中选择数据时使用一个QComhoBox作为代理纟目件申好。这时,就可以从QStyledItemDelegate。

6 Model/View结构的一些概念

6.1 Model/View的基本结构

        在结构中,数据模型为视图组件和代理提供存取数据的标准接口。在Qt中,所有的数据模型类都从QAbstractItemModel继承而来,不管底层的数据结构是如何组织数据的,QAbstractItemModel的子类都以表格的层次结构表示数据,视图组件通过这种规则来存取模型中的数据,但是表现给用户的形式不一样。
        图5-4是数据模型的3种常见表现形式。不管数据模型的表现形式是怎么样的,数据模型中存储数据的基本单元都是项(item),每个项有一个行号、一个列号,还有一个父项(parentitem)。在列表和表格模式下,所有的项都有一个相同的顶层项(rootitem);在树状结构中,行号、列号、父项稍微复杂一点,但是由这3个参数完全可以定义一个项的位置,从而存取项的数据。

6.2 模型索引

        为了保证数据的表示与数据存取方式隔离,数据模型中引入了模型索引(model  index)的概念。通过数据模型存取的每个数据都有一个模型索引,视图组件和代理都通过模型索引来获取数据。
        QModelIndex表示模型索引的类。模型索引提供数据存取的一个临时指针,用于通过数据模
型提取或修改数据。因为模型内部组织数据的结构随时可能改变,所以模型索引是临时的。如果
需要使用持久性的模型索引,则要使用QPersistentModelIndex类。

6.3 行号和列号

        数据模型的基本形式是用行和列定义的表格数据,但这并不意味着底层的数据是用二维数组存储的,使用行和列只是为了组件之间交互方便的一种规定。通过模型索引的行号和列号就可以存取数据。
要获得一个模型索引,必须提供3个参数:行号、列号、父项的模型索引。例如,对于如图
5-4中的表格数据模型中的3个数据项A、B、C,获取其模型索引的代码是:
QModelIndex indexA = model—>index(0,0,QModelIndex());
QModelIndex indexB = model—>index(1,1,QModelIndex());
QModelIndex indexC = model—>index(2,1,QModelIndex());
        在创建模型索引的函数中需要传递行号、列号和父项的模型索引。对于列表和表格模式的数据模型,顶层节点总是用QModelIndex()表示。

6.4 父项

        当数据模型是列表或表格时,使用行号、列号存储数据比较直观,所有数据项的父项(parent item)就是顶层项;当数据模型是树状结构时,情况比较复杂(树状结构中,项一般习惯于称为节点),一个节点可以有父节点,也可以是其他节点的父节点,在构造数据项的模型索引时,必须指定正确的行号、列号和父节点。
        对于图5-4中的树状数据模型,节点A和节点C的父节点是顶层节点,获取模型索引的代码是:
QModelIndex indexA = model—>index(0,0,QModelIndex());
QModelIndex indexC = model—>index(2,1,QModelIndex());
但是,节点B的父节点是节点A,节点B的模型索引由下面的代码生成:
QModelIndex indexB = model—>index(1,0,indexA);

6.5 项的角色

        在为数据模型的一个项设置数据时,可以赋予其不同项的角色(item role)的数据。例如,数据模型类QStandardItemModel的项数据类是QStandardItem,其设置数据的函数是:
void QStandardItem::setData(const QVariant &value,int role=Qt::UserRoIe+1)
        其中,value是需要设置的数据,role是设置数据的角色。一个项可以有不同角色的数据,用于不同的场合。
        role是Qt::ItemDataRole枚举类型,有多种取值,如Qt::DisplayRole角色是在视图组件中显示的字符串,Qt::ToolTipRole是鼠标提示消息,Qt::UserRole可以自定义数据。项的标准角色是Qt::DisplayRole。
        在获取一个项的数据时也需要指定角色,以获取不同角色的数据。
QVariant QStandardItem::data(int role=Qt::UserRoIe+1) const
        为一个项的不同角色定义数据,可以告知视图组件和代理组件如何显示数据。例如,在图5-5
中,项的DisplayRole数据是显示的字符串,DecorationRole是用于装饰显示的属性,ToolTipRole
定义了鼠标提示信息。不同的视图组件对各种角色数据的解释和显示可能不一样,也可能忽略某些角
色的数据。

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

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

相关文章

HAproxy做七层代理+keepalived高可用,实现动静分离,由nginx处理静态页面,tomcat处理动态页面

目录 一、三种软负载均衡器的区别 关于三种负载均衡器的性能对比: 关于三种负载均衡器的代理类型对比: 关于三种负载均衡器的健康检查对比: 二、haproxy的8中负载均衡调度算法 haproxy的会话保持的方式 haproxy的配置文件学习 三、实操…

Starting the Docker Engine...一直转圈

出现的问题: 原因排查: 看了网上的很多篇文章,每个原因都排查了,没有发现问题。 遇到这样的情况应先看自己是否安装成功 打开运行,在空框中输入powershell并点击确定: docker version 显示版本证明安装…

Python启动提示ERROR: [WinError 10013] ��һ�ַ���Ȩ�޲�����ķ�ʽ����һ�������׽��ֵij��ԡ�

启动项目后: 其实就是默认的5000端口号被占用,端口号冲突 ,改下端口即可。 点击:编辑配置 空格加 --port5001 启动成功,点击下图标记位置

SpringBoot-XXLJOB提供动态API调度任务

目录 一、项目版本 二、XXL-JOB提供动态API controller层 service层 三、SpringBoot项目 pom model XxlJobUtil-工具类 XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线&…

java注意项--更新中

前言: 1.大小写规定 1.1.类名和接口名:每个单词首字母大写。如GoodStudent; 是一个单词的时候首字母大写。如Student; 1.2.变量和方法名:第一个首字母小写,后序首字母大写。如firstName; 是一…

Web请求与响应

目录 Postman Postman简介 Postman的使用 请求 简单参数 实体参数 数组参数 集合参数 日期参数 Json参数 路径参数 响应 ResponseBody 统一响应结果 Postman Postman简介 postman是一款功能强大的网页调试与发送网页http请求的Chrome插件,常用于进行…

JavaSE 搜索树

目录 1 概念2 操作2.1 查找2.2 插入2.3 删除 3 性能分析4 和 java 类集的关系 1 概念 二叉搜索树 又称 二叉排序树,它是一棵空树,或者是具有以下性质的二叉树: 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值;若它…

MyBatis的ORM映射

目录 什么是ORM 一,列的别名 二,结果映射 三,总结 什么是ORM ORM:对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简…

【六大排序详解】开篇 :插入排序 与 希尔排序

插入排序 与 希尔排序 六大排序之二 插入排序 与 希尔排序1 排序1.1排序的概念 2 插入排序2.1 插入排序原理2.2 排序步骤2.3 代码实现 3 希尔排序3.1 希尔排序原理3.2 排序步骤3.3 代码实现 4 时间复杂度分析 Thanks♪(・ω・)ノ下一篇文章见&am…

统计分析绘图软件 GraphPad Prism 10 mac功能介绍

GraphPad Prism mac是一款专业的统计和绘图软件,主要用于生物医学研究、实验设计和数据分析。 GraphPad Prism mac功能和特点 数据导入和整理:GraphPad Prism 可以导入各种数据格式,并提供直观的界面用于整理、编辑和管理数据。用户可以轻松地…

MySQL——表的增删查改

目录 一.Create(创建) 1.单行数据 全列插入 2.多行数据 指定列插入 3.插入否则更新 4. 替换 二.Retrieve(读取) 1. select 列 查询 2.where 条件 3.结果排序 4.筛选分页结果 三.Update (修改)…

ROS学习笔记(七)---参数服务器

ROS学习笔记文章目录 01. ROS学习笔记(一)—Linux安装VScode 02. ROS学习笔记(二)—使用 VScode 开发 ROS 的Python程序(简例) 03. ROS学习笔记(三)—好用的终端Terminator 04. ROS学习笔记(四)—使用 VScode 启动launch文件运行多个节点 05. ROS学习笔…

SMARTFORMS打印问题

一、问题概述 项目中碰到EPSON针式打印机,SAP打印出来的三单合一,是想横向打印,结果不管怎么设置打印出来都是纵向的; 二、调整 1、首先调整SMARTFORMS的打印方向,使用T-CODE:SMARTFORMS,如下图&#xf…

嵌入式串口输入详细实例

学习目标 掌握串口初始化流程掌握串口输出单个字符掌握串口输出字符串掌握通过串口printf熟练掌握串口开发流程学习内容 需求 串口循环输出内容到PC机。 串口数据发送 添加Usart功能。 首先,选中Firmware,鼠标右键,点击Manage Project Items 接着,将gd32f4xx_usart.c添…

Dokit 开源库:简化 Android 应用开发的利器

Dokit 开源库:简化 Android 应用开发的利器 一、Dokit 简介二、Dokit 功能三、Dokit 使用3.1 DoKit Android 最新版本3.2 DoKit Android 接入步骤 四、总结 在 Android 应用开发过程中,我们经常需要处理调试、性能优化和用户体验等方面的问题。然而&…

【python】进阶--->并发编程之协程

一、协程 是另外一种实现多任务的方式,只不过比线程占用更小的执行单元(需要的资源).因为它自带cpu上下文,就可以在合适的时机,从一个协程切换到另一个协程. (任务数量多于cpu时)系统在很短的时间内,将cpu轮流分配给不同的任务执行,造成了多任务同时运行的错觉.而每个任务在运行…

全面解析找不到xinput1_3.dll无法继续执行代码的多种解决方案(实用教程)

xinput1_3.dll文件是什么? xinput1_3.dll是一个动态链接库文件,它是DirectInput的组件之一。DirectInput是微软公司开发的一种输入设备驱动程序,用于处理游戏控制器、键盘、鼠标等输入设备的信号。xinput1_3.dll文件主要负责处理游戏控制器的…

年终汇报这么写,升值加薪必有你!

#01 你这么能干, 老板知道吗? — 打工人最怕什么? 最怕你忙前忙后,干活一大堆,气出一身结节,锅还没少背,最后升职加薪没有你,出国旅游不带你;更怕你日常996&#xf…

C语言归并排序(合并排序)算法以及代码

合并排序是采用分治法,先将无序序列划分为有序子序列,再将有序子序列合并成一个有序序列的有效的排序算法。 原理:先将无序序列利用二分法划分为子序列,直至每个子序列只有一个元素(单元素序列必有序),然后再对有序子序…

HTML5+CSS3小实例:纯CSS实现锚点平滑过渡

实例:纯CSS实现锚点平滑过渡 技术栈:HTML+CSS 效果: 源码: 【HTML】 <!DOCTYPE html> <html lang="zh-CN"> <head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"&…