19.[Python GUI] PyQt5中的模型与视图框架-基本原理

news2024/11/27 0:17:32

PyQt中的模型与视图框架

一、Qt中模型与视图相关的类

20221122113129

二、模型与视图的基本原理

  1. MVC把图形界面分为三个部分:模型(Model),视图(View)和控制器(Controller),

    • 模型(Model):用于管理数据,注意,数据不一定需要位于模型之中
    • 视图(View):就是呈现在用户面前的界面外观,视图负责把模型中的数据展现给用户。
    • 控制器(Controller):用于处理用户在用户界面的输入
  2. MVC把需要处理的数据及其显示分离开来。

  3. Qt实现的MVC模型:

    其实Qt中的MVC并不叫MVC,而是叫“MVD”,Qt中没有Controller的说法,而是使用了另外一种抽象: Delegate (委托) ,其行为和传统的MVC是相同的。
    20221122114051

    • Qt把视图和控制器组合在一起,从而形成模型/视图结构。
    • 模型直接与数据进行通信,并为视图和委托提供访问数据的接口。
    • 数据与模型:数据不一定要存储在模型中,数据也可以存储在文件、数据库等其他地方,存储的数据不一定拥有一种数据结构,但是模型通常会把这些数据组织成一种数据结构(比如列表List结构、树形tree结构等),这种结构只是逻辑上的结构,数据本身不一定拥有这种结构。然后视图根据模型提供的逻辑结构显示数据,比如列表视图QListView可以显示把数据组织成列表结构的模型(QStandardItemModel模型实现了该种结构)中的数据。当然了,也可以使用列表视图显示组织为树形结构的数据,但这样做需要做一些比较麻烦的处理才能正确显示,所以通常应使用列表视图显示列表模型的数据,树形视图显示树形结构模型的数据。
    • 为了对用户的输入进行灵活的处理,Qt引入了Delegate(代理/委托)的概念,委托其实就是把用户输入的数据委托给Qt的某个部件处理,比如委托QSpinBox部件来处理用户输入的整数等。另外,委托还会绘制(或渲染)视图中的个别数据项。
    • 模型、视图、委托之间的通信使用Qt的信号和槽机制来完成。
    • 下面以实际的图形界面为例,介绍了MVC各部分之间的功能
      20221122115210
  4. Qt对模型/视图结构的具体实现

  • 模型:Qt使用抽象类QAbstractItemModel来描述模型,所有的模型都是通过子类化该抽象类而实现的。Qt实现了一些标准的现成模型,比如:

    • QStringListModel:用于存储QString项目的列表
    • QStandardItemModel:该模型可以被当做列表模型、表格模型、树形模型来使用
    • QFileSystemModel:该模型提供本地文件系统中的文件和目录信息,模型本身没有任何的数据项目
    • QSqlQueryModel、QSqlTableModel、QSqlRelationalTableModel与数据库有关。
  • 视图:Qt使用抽象类QAbstractItemView来描述视图,所有的视图都是通过子类化该抽象类而实现的。Qt实现了一些标准的现成视图,比如QListView,QTableView,QTreeView等等。

  • 委托:Qt使用抽象类QAbstractItemDelegate来描述委托,Qt实现了两个委托类,QStyledItemDelegate和QItemDelegate,这两个委托之中只能使用其中一个,其区别在于QItemDelegate总是使用一种默认的样式绘制数据项,而QStyledItemDelegate使用当前的样式来绘制数据项,通常使用的是QStyledItemDelegate。Qt默认使用QStyledItemDelegate。

  • 使用Qt MVC 模型/视图的步骤示意如下:

# 创建一个3行3列的表格结构的模型
model = QStandardItemModel(3,3)

# 创建一个表格视图
my_table_view = QTableView()

# 设置模型的数据
model.setData(model.index(0,0),123);
model.setData(model.index(0,1),222);
model.setData(model.index(0,2),333);
model.setData(model.index(1,0),444);
model.setData(model.index(1,1),555);
model.setData(model.index(1,2),666);
model.setData(model.index(2,0),777);
model.setData(model.index(2,1),888);
model.setData(model.index(2,2),999);

# 设置视图的模型
my_table_view.setModel(model)
# 显示视图
my_table_view.show()

20221122135444

三、定位模型中的数据与模型索引

  1. 模型的结构
    在Qt中,无论数据被存储为何种数据结构,模型总是以层次结构(即树形结构)来表示数据,视图按照此约定来访问模型中的数据,若数据是列表或表格结构的数据,则可以把其看做是只含有顶层节点,不含任何叶子节点的树形结构。也就是说,我们在子类化QAbstractItemModel来定义自己的模型结构时,始终应以树形结构为出发点,来组织自己的模型结构。

  2. 模型索引(简称索引)

  • Qt使用模型索引来使数据的表示和访问相分离,视图和委托使用索引来访问模型中的数据项,因此,只有模型知道怎样获取数据。

  • 模型索引不像普通索引仅使用一个数字就能描述,模型索引需要使用3个属性进行描述:行号、列号、父模型索引。虽然模型索引使用行号、列号来定位数据项,但这并不意味着,数据是存储在数组或表格结构中的,使用行号、列号只是允许模型与视图、代理进行通信的一种约定。之所以还需要父模型索引,是因为Qt的模型都是以层次结构(树形结构)来组织的,Qt具体实现时,顶级数据项的父模型索引,使用“无效模型索引”来表示。

  • 模型索引包含一个指向父索引的参数,当使用多个模型时,可避免混淆。

  1. Qt对模型索引的实现
  • Qt使用QModelIndex来实现模型索引,该类提供的索引是一个临时索引,因为模型可能会随时重新组织其内部结构(即数据项可能随时发生变化,比如删除,增加新数据项等),因此模型索引可能会变得无效,所以模型索引不需要也不应该被存储,若需要对数据项进行长时间的引用,应使用QPersistentModelIndex类创建一个持久模型索引。

  • 使用模型索引引用模型中数据项的方法是使用QAbstractItemModel::index()函数。

  • 无效索引模式:使用零参数的QModelIndex类的构造函数创建,即QModelIndex()就表示创建了一个无效模型索引。

  1. Qt常见的模型结构
    20221122142353
  • 树形结构
    // 获取数据项A的模型索引,A的父索引由一个无效模型索引指定
    QModeIndex indexA = model.index(0, 0, QModelIndex())
    // 获取数据项B的模型索引,B位于父索引indexA的第一行第一列的位置
    QModexIndex indexB = model.index(1, 1, indexA)

  • 表格结构
    // 获取数据项B的模型索引,B是顶级数据项,因此其父索引是一个无效索引
    QModelIndex indexB = model.index(1, 2, QModelIndex())

  • 列表结构
    // 获取数据项B的模型索引,B是顶级数据项,因此其父索引是一个无效索引
    QModelIndex indexB = model.index(1, 0, QModelIndex())

四、数据的角色与数据的类型

  1. 同一个类型的数据可以作为不同的角色(或作用)来使用,比如对于字符串"AAA",可以把该字符串以文本的形式显示在视图的相应位置上,也可以把该字符串作为工具提示使用,还可以把该字符串作为what’s this的帮助提示等。由此可见,数据的角色,决定了该数据在视图中的显示方法,角色不同,显示方式也不同。

  2. 数据项与数据元素:位于同一个位置的数据项,并不仅仅只是一个数据元素,本文把组成数据项的数据称为数据元素,每个数据元素都有其自身的角色,比如一个数据项可能会同时含有图标数据元素(角色为Qt::DecorationRole)、文本数据元素(角色为Qt::DisplayRole)、工具提示数据元素(角色为Qt::ToolTipRole)等等。见下图中的数据项"222"
    20221122144907

  3. 因为数据项可以由多个数据元素组成,因此把数据项使用一个单独的类来管理是比较方便的,比如对于QStandardItemModel模型的数据项,就使用了类QStandardItem来专门管理其数据项。

  4. 为了避免概念上的混乱,下面对数据、数据项、项(项目)、节点、单元格、数据元素、模型索引(索引)做一简介

  • 数据:是一个统称,既可以是数据项也可以是数据元素。

  • 数据项:是由多个数据元素组成的,每个数据元素都有自已的角色。

  • 单元格、节点、项目:这三个概念通常用于指模型中的某一个数据项所在的位置, 只是对于不同的模型结构会有不同的称呼, 比如树形结构通常称为节点,表格结构通常称为单元格,而项目是一种更通用的称呼, Qt 中通常称其为项目(item)或数据项;有时也会对以上概念加以区别对待,比如单元格XXX的数据项,此时单元格表示位置,数据项就表示实际存储的数据。不管怎样,模型中某个数据项所在位置都是需要使用模型索引来指定的,因此单元格、节点、项目、数据项、模型索引这几个概念通常会根据不同的情形用于表示模型中的某个位置。

  1. 标准的数据角色由枚举Qt::ItemDataRole来描述,见下表。数据角色由QAbstractItemModel::setData()函数的第 3 个参数指定,其使用方法如下,其效果见第 2 点图示中第 1 行第 2 列的单元格:

    • model.setData(model.index(0,1),222,Qt::DisplayRole); //设置显示的文本
    • model.setData(model.index(0,1),QIcon(“F:/1i.png”),Qt::DecorationRole); //设置图标
    • model.setData(model.index(0,1),“EEE”,Qt::ToolTipRole); //设置工具提示

    20221122150748

五、选择视图中的数据项(选择模型)

选择模型: 对视图内项目的选择

Qt 使用 QItemSelectionModel 类来实现。所有的标准视图都有自已默认的选择模型。视图可以使用 QAbstractItemView::selectionModel()函数和QAbstractItemView::setSelectionModel()来获取和设置选择模型。通常不需要对选择模型进行设置。

六、Qt 实现的便利类

Qt 通过模型/视图框架结构实现了一些标准的方便使用的部件,使用这些便利部件比较简单。

这些类是 QListWidget、 QTreeWidget、 QTableWidget。


小手一抖,点个赞再走哦~~~

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

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

相关文章

Git大型文件存储

什么是 Git LFS? Git 是跟踪代码库演变和与同行高效协作的绝佳选择。但是,当您要跟踪的存储库非常大时会发生什么? 如果您考虑一下,存储库变得庞大的主要原因大致有两个: 他们积累了非常非常长的历史(项目…

【C】文件操作fopen与fclose

目录 函数 1.fopen 2.fclose 3.freopen 函数 头文件 #include<stdio.h> 1.fopen FILE *fopen(const char *restrict dilename,const char* restrict mode); 作用&#xff1a;打开文件参数&#xff1a; 第一个是含有要打开文件名的字符串&#xff08;"文件名…

肝了一周的八万字Redis实战篇

Redis实战篇 文章目录Redis实战篇开篇导读1. 短信登录2. 商户查询缓存3. 优惠卷秒杀4. 附近的商户5. UV统计6. 用户签到7. 好友关注8. 达人探店一、短信登录1. 导入黑马点评项目1.1 导入SQL1.2 有关当前模型1.3 导入后端项目1.4 导入前端工程1.5 运行前端项目2. 基于Session实现…

【杂谈】快来看看如何使用LGMT这样的蜜汁缩写来进行CodeReview吧!

文章目录一、先从一个梗开始说起吧&#xff01;二、什么是LGTM&#xff1f;2.1 LGTM 是什么意思&#xff1f;2.2 蹭梗品牌故事2.3 虚假的CodeReview三、Code Review中的蜜汁缩写四、参考链接一、先从一个梗开始说起吧&#xff01; 公司最近在如火如荼的开展CodeReview活动&…

Reinforcement learning from demonstration through shaping(Wiewiora 2003)

摘要 强化学习中的一个重要问题是如何以有原则的方式整合专家知识&#xff0c;尤其是当我们扩展到现实世界的任务时。在本文中&#xff0c;我们提出了一种在不改变最优策略的情况下将任意建议纳入强化学习agent的奖励结构的方法。 该方法将 Ng 等人 (1999) 提出的基于势能的塑…

1530_AURIX_TriCore内核架构_通用寄存器以及系统寄存器

全部学习汇总&#xff1a; GreyZhang/g_tricore_architecture: some learning note about tricore architecture. (github.com) 继续看一下内核手册&#xff0c;这次了解一下通用寄存器以及系统寄存器。最近一段时间最复位以及trap困扰了许久&#xff0c;看看这里面是否能够获取…

黄河水稻山东智慧 国稻种芯·中国水稻节:济南泉城米袋子

黄河水稻山东智慧 国稻种芯中国水稻节&#xff1a;济南泉城米袋子 新闻中国采编网 中国新闻采编网 谋定研究中国智库网 中国农民丰收节国际贸易促进会 国稻种芯中国水稻节 中国三农智库网-功能性农业农业大健康大会报道&#xff1a;又是一年春天。济南黄河流域吴家堡水稻田旁的…

数据挖掘与机器学习:数据挖掘算法原理与实践:数据预处理

目录 第一关&#xff1a;标准化 任务描述&#xff1a; 相关知识&#xff1a; 一、为什么要进行标准化 二、Z-score标准化 三、Min-max标准化 四、MaxAbs标准化 编程要求&#xff1a; 测试说明&#xff1a; 第二关&#xff1a;非线性转换 任务描述&#xff1a; 相关知…

【LeetCode】878. 第 N 个神奇数字

题目描述 一个正整数如果能被 a 或 b 整除&#xff0c;那么它是神奇的。 给定三个整数 n , a , b &#xff0c;返回第 n 个神奇的数字。因为答案可能很大&#xff0c;所以返回答案 对 109 7 取模 后的值。 示例 1&#xff1a; 输入&#xff1a;n 1, a 2, b 3 输出&#xff…

stm32cubemx hal学习记录:FreeRTOS互斥量

一、互斥量 1、互斥量用于互锁&#xff0c;可以充当资源保护的令牌&#xff0c;当一个任务希望访问某个资源时&#xff0c;它必须先获取令牌&#xff0c;当任务使用完资源后&#xff0c;必须返还令牌&#xff0c;以便其他任务可以访问该资源。 2、互斥量一般用于临界资源保护…

[附源码]计算机毕业设计JAVA教师档案管理系统

[附源码]计算机毕业设计JAVA教师档案管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybati…

LabVIEW通信-CAN

文章目录CANcan总线特点位定位与同步标识符检验滤波报文传输类型CAN CAN属于OSI的物理层与数据链路层 can总线特点 网络各节点之间的数据通信实时性强 开发周期短 结构简单&#xff08;只有两根线与外部相连&#xff0c;内部继承了错误探测和管理模块&#xff09; 数据通信没…

Spring IOC

一、为什么要使用Spring&#xff1f; Spring 是个java企业级应用的开源开发框架。Spring主要用来开发Java应用&#xff0c;但是有些扩展是针对构建J2EE平台的web应用。Spring 框架目标是简化Java企业级应用开发&#xff0c;并通过POJO为基础的编程模型促进良好的编程习惯。 为…

RPA案例|云扩助力保险行业开启超自动化运营新阶段

近五年&#xff0c;全球平均保险深度总体呈小幅平稳下降趋势&#xff0c;2021年中国保险深度为4.15%&#xff0c;全球平均保险深度为5.96%&#xff0c;而美国、英国等发达国家的保险深度则保持在10%以上&#xff0c;中国保险深度仍然具有很大的上升空间。 为进一步拓展增量空间…

软考是什么?---2023年软考最全解析

软考是什么&#xff1f; 软考全称为&#xff1a;计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试&#xff0c;发证机构为国家人力资源和社会保障部、工业和信息化部&#xff0c;简称为&#xff1a;人社部和工信部。中日韩三国互认&#xff0c;证书的含金量很高…

Navicat操作数据库与Mysql常见命令操作实战

一&#xff1a;Navicat下载与安装 官网下载链接&#xff1a;Navicat 下载完后直接安装即可 二&#xff1a;数据库的连接 1.打开Navicat软件&#xff0c;点击左上角连接按钮&#xff0c;选择mysql数据库 输入完成后双击连接名&#xff0c;连接成功后&#xff0c;小海豚变绿色 …

Advances in Graph Neural Networks笔记5:Dynamic Graph Neural Networks

诸神缄默不语-个人CSDN博文目录 本书网址&#xff1a;https://link.springer.com/book/10.1007/978-3-031-16174-2 本文是本书第五章的笔记。 懒得看了&#xff01;反正我也不是做这个的。以后要是真的去做动态图了也不是没资源找&#xff0c;这个我懒得看了&#xff0c;就写一…

CentOS 7安装Redis+Springboot整合Redis

1、虚拟环境条件&#xff1a; 已安装VMwareVMware Tools 使用的是视图界面并配置了基本开发环境&#xff0c;参照超详细VMware安装CentOs图文教程_Sq夏颜的博客-CSDN博客 2、直接把已经下载好的redis安装包拖进来&#xff0c;下载地址&#xff1a;CRUG网站 3、解压 tar -zxv…

美国fba海运清关基本流程

美国fba海运清关是美国物流运输的重要组成部分&#xff0c;准备好清关材料和正确流程是确保货物安全快速进口到美国的关键。虽然很多客户会选择双清包税的方式&#xff0c;但是当跨境电商越来越大的时候&#xff0c;双清包税的成本也会相应增加。选择自税不包清关&#xff0c;按…

react配置项目路径别名@

为什么有的项目引入路径写可以&#xff0c;自己的不行呢&#xff1f; 因为别人的项目是配置过路径别名的&#xff0c;就表示src目录&#xff0c;因此我们也需要配置一遍&#xff0c;以下是react项目示范&#xff0c;vue项目同理。 ts对指向src目录的提示是不支持的&#xff0…