模型和视图框架(概念)

news2025/1/15 12:54:32

MVC(Model-View-Controller)是一种设计模式。

  • Model(模型)是应用对象,用来显示模型
  • View (视图)是用户界面,用来显示数据
  • Controller(控制)定义用户界面对用户输出的反映方式

 模型/视图类可以分为上述三组:模型、视图和委托。这些组件中的每一个都由抽象类定义,这些抽象类提供通用接口,在某些情况下,还提供功能的默认实现。

 模型:

模型的基类为:QAbstractItemModel类,此类定义视图和委托用于访问数据的接口。数据本身不必存储在模型中;它可以保存在由单独的类、文件、数据库或某些其他应用程序组件提供的数据结构或存储库中。常用的视图有:表格、树、列表。

Qt提供了一些现成的模型,可用于处理数据项

  • QStringListModel 用来存储一个简单的QString列表
  • QStandardItemModel 管理复杂的树形结构数据项,,每一个数据项可以包含任意的数据
  • QFileSystemModel提供本地文件系统中文件和目录的信息
  • QSqlQuerryModel,QSqlTableModel和QSalRelationTableModel 用来访问数据库

无法满足需求的话,可以子类化QAbstractItemModel、 QAbstractListModel、QAbstractTableModel来创建自定义的模型

视图:

在Qt中:QListView列表视图,QTreeView树视图、QTableView表格视图,这些类都基于QAbstractItemView抽象基类。

 委托:

QAbstractItemDelegate是委托的抽象基类,子类主要分为以下两种:

  • QStyledItemDelegate类(默认委托类)使用当前样式来绘制项目
  • QItemDelegate类 
  • QStyledItemDelegate和QItemDelegate是绘制和为视图中的项目提供编辑器的独立替代方法。

注意:使用时只能选择一种,一般的话使用QStyledItemDelegate

使用模型和视图:

 使用QFileSystemModel 文件模型,并用QListView 和QTreeView显示

#include "widget.h"

#include <QApplication>
#include<QFileSystemModel>//模型
#include<QSplitter>
#include<QTreeView>//视图
#include<QListView>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QSplitter * sp=new QSplitter;
    QFileSystemModel model;//创建文件系统模型
    model.setRootPath(QDir::currentPath());//设置要监视的目录
    QTreeView *tree=new QTreeView(sp);//创建树形视图
    tree->setModel(&model);//设置模型
    tree->setRootIndex(model.index(QDir::currentPath()));//指定根索引
    QListView *list=new QListView(sp);//创建列表视图
    list->setModel(&model);
    list->setRootIndex(model.index(QDir::currentPath()));//指定根索引
    sp->show();
    return a.exec();
}

模型类:

常用的三种模型为:list(列表)  table (表格) tree(树)

 

1. 模型索引:

为了确保数据的表示形式与访问数据的方式分开,引入了模型索引的概念。可以通过模型获得的每条信息都由模型索引表示。视图和委托使用这些索引来请求要显示的数据项

模型索引提供对信息片段的临时引用,并可用于通过模型检索或修改数据 ,但模型可能会不时重组其内部结构,因此模型索引可能会变得无效。

  • 临时的模型索引由 QModelIndex提供
  • 持久模型索引由QPersistentModelIndex类提供   (需要长时间对信息引用)

 获取模型索引的话,必须指定行号、列号和父项的模型索引。

 2.行和列:

在其最基本的形式中,模型可以作为一个简单的表进行访问(行和列都是从0开始),可以通过向模型指定其行号和列号来检索有关任何给定项目的信息。

QModelIndex index=model->index(行,列,父项)

 在表格和列表模型中,所有数据项都是以根项(Root Item)为父项(也称为顶层数据项)获取顶层数据项使用 QModelIndex() 表示。

以表格模型为例:

QModelIndex indexA =model->index(0,0,QModelIndex());//获取A的模型索引
QModelIndex indexB =model->index(1,1,QModelIndex());//获取B的模型索引
QModelIndex indexC =model->index(2,1,QModelIndex());//获取C的模型索引

 3.父项:

在表或列表视图中使用数据时,模型提供的项数据的类似表的界面是理想的选择;行号和列号系统与视图显示项目的方式完全一致。但是,树视图等结构要求模型向其中的项公开更灵活的接口,因此,每个项也可以是另一个项表的父项,其方式与树视图中的顶级项可以包含另一个项列表的方式大致相同。

树模型:

QModelIndex indexA =model->index(0,0,QModelIndex());//获取A的模型索引
//指定父项为A
QModelIndex indexB =model->index(1,0,indexA);//获取B的模型索引
QModelIndex indexC =model->index(2,1,QModelIndex());//获取C的模型索引

3.项目角色: 

 模型中的项可以为其他组件执行各种角色,从而允许为不同情况提供不同类型的数据,例如Qt::DisplayRole用于访问视图中的字符串。通常,项目中包含许多不同的角色的数据,标准角色由Qt::ItemDataRole定义。

模型传递与项目对应的模型索引,并通过指定一个角色来获取我们想要的数据类型,从而向模型询问项目的数据:

QVariant value=model->data(index,role);

 常见的角色类型:

Qt::DisplayRole要以文本形式呈现的关键数据
Qt::DecorationRole要以图标形式呈现为修饰的数据
Qt::EditRole适合在编辑器中编辑的表单中的数据
Qt::ToolTipRole项目的工具提示中显示的数据
Qt::StatusTipRole状态栏中显示的数据
Qt::WhatsThisRole在“What is this?”模式下为项目显示的数据
Qt::SizeHintRole将提供给视图的项的大小提示
Qt::FontRole用于使用默认委托呈现的项的字体
Qt::TextAlignmentRole使用默认委托呈现的项的文本对齐方式
Qt::BackgroundRole用于使用默认委托呈现的项的背景画笔
Qt::ForegroundRole用于使用默认委托呈现的项目的前景色画笔(通常为文本颜色)
Qt::CheckStateRole此角色用于获取项目的已检查状态
Qt::InitialSortOrderRole此角色用于获取标题视图节的初始排序顺序
Qt::UserRole可用于特定于应用程序的第一个角色

 例子:使用QStandardItemModel 创建一个模型,并获取角色类型

  • 获取模型的父项使用 invisibleRootItem()
  • 设置ModelIndex时 父项的表示为QModelIndex()
    QStandardItemModel model;//创建一个标准模型
    QStandardItem *ParentItem=model.invisibleRootItem();//获取根项
    QStandardItem *item=new QStandardItem;//创建一个标准子项
    item->setText("11111111");//设置内容
    QPixmap pixmap(40,40);//创建一个图片
    pixmap.fill("red");
    item->setIcon(QIcon(pixmap));//设置图标
    item->setToolTip("index1");
    ParentItem->appendRow(item);//添加子项
    //修改父项
    ParentItem=item;//将item设父项
    QStandardItem *item1=new QStandardItem;//创建一个标准子项
    item1->setText("22222222");//设置内容
    QPixmap pixmap1(40,40);//创建一个图片
    pixmap1.fill("blue");
    item1->setIcon(QIcon(pixmap1));//设置图标
    item1->setToolTip("index2");
    ParentItem->appendRow(item1);//添加子项

    //使用setData()来设置
    QStandardItem *item2=new QStandardItem;//创建一个标准子项
    QPixmap pixmap2(40,40);//创建一个图片
    pixmap2.fill("green");
    item2->setData("33333333",Qt::EditRole);//设置文本
    item2->setData(QIcon(pixmap2),Qt::DecorationRole);//设置图标
    item2->setData("index3",Qt::ToolTipRole);//设置工具提示
    ParentItem->appendRow(item2);//添加子项
    //创建一个视图
    QTreeView view;
    view.setModel(&model);
    view.show();

    //输出项目的内容
    QModelIndex indexA=model.index(0,0,QModelIndex());//获取item
    qDebug()<<model.rowCount(indexA);//获取该索引的子项
    qDebug()<<model.data(indexA,Qt::ToolTipRole).toString();//获取工具提示
    qDebug()<<model.data(indexA,Qt::EditRole).toString();//获取文本框内容
    qDebug()<<model.data(indexA,Qt::DecorationRole);//获取图标

视图类:

在模型/视图体系结构中,视图从模型中获取数据项并将其呈现给用户。数据的呈现方式不需要类似于模型提供的数据的表示形式,并且可能与用于存储数据项的基础数据结构完全不同

内容和表示的分离通过使用 QAbstractItemModel 提供的标准模型接口、QAbstractItemView 提供的标准视图接口以及使用以一般方式表示数据项的模型索引来实现。视图通常管理从模型获取的数据的整体布局。它们可以自己呈现单个数据项,也可以使用委托来处理呈现和编辑功能。除了显示数据外,视图还处理项目之间的导航以及项目选择的某些方面。

    QSplitter * sp=new QSplitter;
    QFileSystemModel model;//创建文件系统模型
    model.setRootPath(QDir::currentPath());//设置要监视的目录

    QTreeView *tree=new QTreeView(sp);//创建树形视图
    tree->setModel(&model);//设置模型
    tree->setRootIndex(model.index(QDir::currentPath()));//指定根索引

    QListView *list=new QListView(sp);//创建列表视图
    list->setModel(&model);
    list->setRootIndex(model.index(QDir::currentPath()));//指定根索引

    QTableView *table=new QTableView(sp);//创建表格视图
    table->setModel(&model);
    table->setRootIndex(model.index(QDir::currentPath()));//指定索引
    sp->show();

 

处理项目的选择 :

处理视图的选择的机制由QItemSelectionModel类提供,默认情况下所有标准视图都构造自己的选择模型,并以正常方式与它们进行交互。

  • selectionModel()获取选择模型
  • setSelectionModel()指定选择模型

当我们想要为同一模型数据提供多个一致的视图时,控制视图使用的选择模型的能力非常有用

 视图之间共享选择

    QSplitter * sp=new QSplitter;
    QFileSystemModel model;//创建文件系统模型
    model.setRootPath(QDir::currentPath());//设置要监视的目录

    QTreeView *tree=new QTreeView(sp);//创建树形视图
    tree->setModel(&model);//设置模型
    tree->setRootIndex(model.index(QDir::currentPath()));//指定根索引

    QTableView *table=new QTableView(sp);//创建表格视图
    table->setModel(&model);
    table->setRootIndex(model.index(QDir::currentPath()));//指定索引
    
    table->setSelectionModel(tree->selectionModel());//实现同步
    sp->show();

 

 委托类:

与模型-视图-控制器模式不同,模型/视图设计不包括用于管理与用户交互的完全独立的组件。通常,视图负责向用户呈现模型数据,并负责处理用户输入。为了在获取此输入的方式上具有一定的灵活互由委托执行。这些组件提供输入功能,还负责呈现某些视图中的单个项。用于控制委托的标准接口在 QAbstractItemDelegate 类中定义。

委托通过实现paint()和sizeHint()函数来使它们可以渲染自身的内容,简单的基于部件的委托可以通过QItemDelegate来实现,不需要QAbstractItemDelegate,这样可以使用这些函数的默认项实现

使用现有委托:

标准委托类使用QStyledItrmDelegate的实例来提供编辑工具,所有标准角色都由标准视图使用的默认委托处理。

  • itemDelegate()返回委托
  • setItenDelegate()设置委托

 参考文档:

QAbstractItemDelegate

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

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

相关文章

CPU100%,怎么快速定位?

一台机器&#xff0c;CPU100%&#xff0c;如何找到相关服务&#xff0c;如何定位问题代码&#xff0c;今天简单分享下思路。假设&#xff0c;服务器上部署了若干Java站点服务&#xff0c;以及若干Java微服务&#xff0c;突然收到运维的CPU异常告警。如何定位是哪个服务进程导致…

是时候给钉钉和腾讯会议算算账了

杨净 萧箫 发自 凹非寺量子位 | 公众号 QbitAI这几天&#xff0c;工作和上课等事情开始有回归线下的迹象&#xff0c;腾讯会议、钉钉似乎也可以松口气了。毕竟云会议的这两大APP&#xff0c;前段时间一直在被网友找平替。一来&#xff0c;它们要收费了&#xff1b;二来&#xf…

【有营养的算法笔记】整数二分和浮点二分的全面分析

&#x1f451;作者主页&#xff1a;进击的安度因 &#x1f3e0;学习社区&#xff1a;进击的安度因&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;有营养的算法笔记 文章目录一、铺垫二、整数二分模板分析三、模板应用 —— 数的范围四、浮点二分模板分析…

简单引入JQuery

简单引入JQuery前言环境配置下载官网的JQuery到本机引入JQuery到Html文件中前言 作为一个兢兢业业的后端程序猿&#xff0c;这里为了方便自己搭建的项目更加合理&#xff0c;使自己写的接口对前端也更加友好。所以我决定&#xff0c;从头开始学习下前端知识。 环境配置 下载…

[附源码]JAVA毕业设计翔隆生鲜超市进货管理系统(系统+LW)

[附源码]JAVA毕业设计翔隆生鲜超市进货管理系统&#xff08;系统LW&#xff09; 项目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 …

聚宽量化入门量化策略是什么?

聚宽量化入门量化策略JoinQuant聚宽API文档&#xff1a;MetaTradeAPI (metatradeapi) - Gitee.com 获取要操作的股票或指数成分股 1、# 导入函数库&#xff1b; 2、import jqdata&#xff1b; 3、# 初始化函数&#xff0c;设定基准 def initialize(context)&#xff1a; …

每日一题 —— LC. 1687 从仓库到码头运输箱子(难度很大,但值得好好消化的一道题)

1687. 从仓库到码头运输箱子 你有一辆货运卡车&#xff0c;你需要用这一辆车把一些箱子从仓库运送到码头。这辆卡车每次运输有 箱子数目的限制 和 总重量的限制 。 给你一个箱子数组 boxes和三个整数 portsCount, maxBoxes 和 maxWeight &#xff0c;其中 boxes[i][portsi,we…

web前端期末大作业:基于HTML+CSS+JavaScript制作鲜花礼品在线购物网站设计(19页)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

代码随想录刷题Day59 | 503. 下一个更大元素 II | 42. 接雨水

代码随想录刷题Day59 | 503. 下一个更大元素 II | 42. 接雨水 503. 下一个更大元素 II 题目&#xff1a; 给定一个循环数组 nums &#xff08; nums[nums.length - 1] 的下一个元素是 nums[0] &#xff09;&#xff0c;返回 nums 中每个元素的 下一个更大元素 。 数字 x 的…

云与开源,共植数字世界的根

摘要&#xff1a;本文整理自阿里巴巴集团副总裁、阿里巴巴开源技术委员会负责人贾扬清&#xff0c;在 Flink Forward Asia 2022 主会场的开场致辞。Tips&#xff1a;点击「阅读原文」获取演讲 ppt&#xff5e;云和开源&#xff0c;共生、共长、共植数字世界的根。从在云上使用开…

SAP PS 第17节 项目产成品产出

SAP PS 第17节 项目产成品产出及差异处理1 模拟场景说明1.1 拖拽负库存1.2 发料原材料及报工1.3 执行副产品入库migo发预留1.4 CNS0交货1.5 后面开票产生收入按照项目结算即可项目上有一类比较另类的玩法&#xff0c;就是舍弃PP&#xff0c;依靠网络活动的负库存&#xff0c;实…

Web前端大作业—个人网页(html+css+javascript)我的家乡新密 (15页)含课程设计

家乡旅游景点网页作业制作 网页代码运用了DIV盒子的使用方法&#xff0c;如盒子的嵌套、浮动、margin、border、background等属性的使用&#xff0c;外部大盒子设定居中&#xff0c;内部左中右布局&#xff0c;下方横向浮动排列&#xff0c;大学学习的前端知识点和布局方式都有…

2030年销售额突破200亿美元!瑞萨电子揭秘智能汽车版图

汽车正在成为继手机之后的下一个智能终端&#xff0c;并且已经成为全球各大芯片头部厂商的必争之地。 过去&#xff0c;汽车芯片市场主要由恩智浦、瑞萨电子、TI等传统汽车芯片巨头垄断&#xff0c;外来者鲜有机会可以入局。但近几年&#xff0c;包括高通、英特尔等全球各大芯…

【无人机】基于Fast行军树(FMT)求解无人机故障路径规划问题附matlab代码和论文

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

ElementPlus弹窗之后让外部区域可编辑

原始的el-dialog弹出以后外部区域是不可编辑的。 为最外层的父元素添加样式 同时给dialog本身添加样式

【工作日推算】JS计算当前时间前N个工作日(去除周末及节假日,文尾附源码下载)

【写在前面】前些日子忙了几天有关指标对比分析的功能&#xff0c;因为系统是对接券商类的业务&#xff0c;所以他们比较关注的是工作日的数据波动&#xff0c;因此前端指标对比数据需要拿工作日的&#xff0c;不然他们停市的数据比较也没用&#xff0c;故而今天针对之前实现的…

如何快速搞懂一家公司?

如果没有快速作为前提&#xff0c;你的搞懂&#xff0c;价值会大打折扣。 一.研究一家公司需要的宏观视野 1.把握长期明确趋势 看清宏观大背景能为你搞懂公司做出铺垫&#xff0c;同时看清这个公司和宏观的密切程度是怎样的&#xff0c;也决定了需要多大程度关注宏观变化。 …

【基于Pycharm的Django3教程】Part1:初识Django

文章目录1 初识Django1.1 django的安装1.2 创建django项目1.3 两种创建方式的对比1.4 默认文件介绍1.5 APP的创建和说明1.6 启动运行django1.7 模板和静态文件1.8 模板语法1.9 请求和响应1.10 orm数据库操作1.11 ORM 数据库案例&#xff1a;用户管理1 初识Django 1.1 django的…

22 条 API 设计的最佳实践

在这个微服务的世界里&#xff0c;后端API的一致性设计是必不可少的。 今天&#xff0c;我们将讨论一些可遵循的最佳实践。我们将保持简短和甜蜜——所以系好安全带&#xff0c;出发咯&#xff01; 首先介绍一些术语 任何API设计都遵循一种叫做“面向资源设计”的原则&#…

TOWER x Binance NFT 桥接教程

TOWER x Binance NFT 销售的 TOWER 门票和人物化身皮肤 NFT 现在可以从 BNB 链桥接到 Polygon 啦&#xff01; 一起来看看如何将你的 TOWER x Binance NFT 从 BNB 链转移到 Polygon&#x1f447; 1、到 BinanceNFT 用户中心提取你的 TOWER NFT 到 BNB Chain&#xff0c;然后等待…