Qt 学习之路 2(41):model/view 架构
Qt 学习之路 2(41):model/view 架构
有时,我们的系统需要显示大量数据,比如从数据库中读取数据,以自己的方式显示在自己的应用程序的界面中。早期的 Qt 要实现这个功能,需要定义一个组件,在这个组件中保存一个数据对象,比如一个列表。我们对这个列表进行查找、插入等的操作,或者把修改的地方写回,然后刷新组件进行显示。这个思路很简单,也很清晰,但是对于大型程序,这种设计就显得苍白无力。比如,在一个大型系统中,你的数据可能很大,全部存入一个组件的数据对象中,效率会很低,并且这样的设计也很难在不同组件之间共享数据。如果你要几个组件共享一个数据对象,要么你就要用存取函数公开这个数据对象,要么你就必须把这个数据对象放进不同的组件分别进行维护。
Smalltalk 语言发明了一种崭新的实现,用来解决这个问题,这就是著名的 MVC 模型。对这个模型无需多言。MVC 是 Model-View-Controller 的简写,即模型-视图-控制器。在 MVC 中,模型负责获取需要显示的数据,并且存储这些数据的修改。每种数据类型都有它自己对应的模型,但是这些模型提供一个相同的 API,用于隐藏内部实现。视图用于将模型数据显示给用户。对于数量很大的数据,或许只显示一小部分,这样就能很好的提高性能。控制器是模型和视图之间的媒介,将用户的动作解析成对数据的操作,比如查找数据或者修改数据,然后转发给模型执行,最后再将模型中需要被显示的数据直接转发给视图进行显示。MVC 的核心思想是分层,不同的层应用不同的功能。
Qt 4 开始,引入了类似的 model/view 架构来处理数据和面向最终用户的显示之间的关系。当 MVC 的 V 和 C 结合在一起,我们就得到了 model/view 架构。这种架构依然将数据和界面分离,但是框架更为简单。同样,这种架构也允许使用不同界面显示同一数据,也能够在不改变数据的情况下添加新的显示界面。为了处理用户输入,我们还引入了委托(delegate)。引入委托的好处是,我们能够自定义数据项的渲染和编辑。
Model View 概览
如上图所示,模型与数据源进行交互,为框架中其它组件提供接口。这种交互的本质在于数据源的类型以及模型的实现方式。视图从模型获取模型索引,这种索引就是数据项的引用。通过将这个模型索引反向传给模型,视图又可以从数据源获取数据。在标准视图中,委托渲染数据项;在需要编辑数据时,委托使用直接模型索引直接与模型进行交互。
总的来说,model/view 架构将传统的 MV 模型分为三部分:模型、视图和委托。每一个组件都由一个抽象类定义,这个抽象类提供了基本的公共接口以及一些默认实现。模型、视图和委托则使用信号槽进行交互:
- 来自模型的信号通知视图,其底层维护的数据发生了改变;
- 来自视图的信号提供了有关用户与界面进行交互的信息;
- 来自委托的信号在用户编辑数据项时使用,用于告知模型和视图编辑器的状态。
所有的模型都是QAbstractItemModel的子类。这个类定义了供视图和委托访问数据的接口。模型并不存储数据本身。这意味着,你可以将数据存储在一个数据结构中、另外的类中、文件中、数据库中,或者其他你所能想到的东西中。我们将在后面再详细讨论这些内容。
QAbstractItemModel提供的接口足够灵活,足以应付以表格、列表和树的形式显示的数据。但是,如果你需要为列表或者表格设计另外的模型,直接继承QAbstractListModel和QAbstractTableModel类可能更好一些,因为这两个类已经实现了很多通用函数。关于这部分内容,我们也会在后文中详述。
Qt 内置了许多标准模型:
QStringListModel:存储简单的字符串列表。QStandardItemModel:可以用于树结构的存储,提供了层次数据。QFileSystemModel:本地系统的文件和目录信息。QSqlQueryModel、QSqlTableModel和QSqlRelationalTableModel:存取数据库数据。
正如上面所说,如果这些标准模型不能满足你的需要,就必须继承QAbstractItemModel、QAbstractListModel或者QAbstractTableModel,创建自己的模型类。
Qt 还提供了一系列预定义好的视图:QListView用于显示列表,QTableView用于显示表格,QTreeView用于显示层次数据。这些类都是QAbstractItemView的子类。这意味着,如果你要创建新的视图类,则可以继承QAbstractItemView。则是所有委托的抽象基类。自 Qt 4.4 依赖,默认的委托实现是
QAbstractItemDelegateQStyledItemDelegate。但是,QStyledItemDelegate和QItemDelegate都可以作为视图的编辑器,二者的区别在于,QStyledItemDelegate使用当前样式进行绘制。在实现自定义委托时,推荐使用QStyledItemDelegate作为基类,或者结合 Qt style sheets。
如果你觉得 model/view 模型过于复杂,或者有很多功能是用不到的,Qt 还有一系列方便使用的类。这些类都是继承自标准的视图类,并且继承了标准模型。这些类并不是为其他类继承而准备的,只是为了使用方便。它们包括QListWidget、QTreeWidget和QTableWidget。这些类远不如视图类灵活,不能使用另外的模型,因此只适用于简单的情形。
Qt 学习之路 2(41):model/view 架构的更多相关文章
- Qt学习之路(45): 自定义model之一
前面我们说了Qt提供的几个预定义model.但是,面对变化万千的需求,那几个model是远远不能满足我们的需要的.另外,对于Qt这种框架来说,model的选择首先要能满足绝大多数功能的需要,这就是说, ...
- Qt学习之路:自定义Model三篇,自定义委托等等
http://devbean.blog.51cto.com/448512/d-8/p-2
- Qt 学习之路 2(31):贪吃蛇游戏(1)
Qt 学习之路 2(31):贪吃蛇游戏(1) 豆子 2012年12月18日 Qt 学习之路 2 41条评论 经过前面一段时间的学习,我们已经了解到有关 Qt 相当多的知识.现在,我们将把前面所讲过的知 ...
- Qt 学习之路 2(30):Graphics View Framework
Qt 学习之路 2(30):Graphics View Framework 豆子 2012年12月11日 Qt 学习之路 2 27条评论 Graphics View 提供了一种接口,用于管理大量自定义 ...
- 第15.23节 PyQt(Python+Qt)入门学习:Model/View架构中QListView视图配套Model的开发使用
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 QListView理论上可以和所有QAbstractItemModel派生的类如QStri ...
- 第15.22节 PyQt(Python+Qt)入门学习:Model/View架构详解
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.简介 在PyQt和Qt中,Model/View架构是图形界面开发时用于管理数据和界面展现方式的关 ...
- 第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解
老猿Python博文目录 老猿Python博客地址 一.概述 在PyQt图形界面中,支持采用Model/View架构实现数据和界面逻辑分离,其中Model用于处理数据存储,View用于界面数据展现,当 ...
- PyQt(Python+Qt)学习随笔:model/view架构中类QStandardItemModel的使用方法
老猿Python博文目录 老猿Python博客地址 一.概述 QStandardItemModel是QAbstractItemModel的派生类,用于在Model/View架构中存储自定义数据的通用模 ...
- PyQt(Python+Qt)学习随笔:Model/View架构中的Model模型概念
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 Model/View架构中的Model模型Model与数据源通信,为体系结构中的其他组件提供数据接口 ...
随机推荐
- 对get post请求的封装
HttpUtil.java package com.dhc.task.wx.util; import java.io.BufferedReader; import java.io.IOExceptio ...
- Texture Filter
[Texture Filter] 我们的纹理是要贴到三维图形表面的,而三维图形上的pixel中心和纹理上的texel中心并不一至(pixel不一定对应texture上的采样中心texel),大小也不一 ...
- GCC笔记(警告.优化以及调试选项)
GCC提供了大量的警告选项,对代码中可能存在的问题提出警告,通常可以使用-Wall来开启以下警告: -Waddress -Warray-bounds (only with -O2) -Wc++0x-c ...
- EKF model&realization
REF: https://pythonrobotics.readthedocs.io/en/latest/modules/localization.html#unscented-kalman-filt ...
- Zend Studio 10汉化方法
选择Help菜单->Install New Software...在Work with框中复制此地址:http://download.eclipse.org/technology/babel/u ...
- Docker学习笔记_安装和使用Redis
一.准备 1.宿主机OS:Win10 64位 2.虚拟机OS:Ubuntu18.04 3.操作账号:Docker 二.安装过程 1.搜索Redis su ...
- QT编译时出现警告 Warning: Class Node implements the interface QGraphicsItem but does not list it in Q_INTERFACES. qobject_cast to QGraphicsItem will not work!
1.一定要将public QObject放在public QGraphicsItem的前面,并且在该类的定义中添加Q_OBJECT宏. class XXGraphicsItem : public QO ...
- 关于wamp中升级PHP+Apache 的问题
首先个人不建议wamp中升级php版本,如果你不信可以试一试,当你php升级后发想,奥,Apache版本不匹配,然后又去升级Apache,结果搞了半天,弄出来了就好,要是没出来,可能你会气死(好吧,气 ...
- GO程序设计2——面向过程基础知识
1 简介 GO语言google开发的新语言.有如下特性: 自动垃圾回收.更丰富的内置数据类型.函数多返回值.错误处理.匿名函数和闭包.类型和接口.并发编程.反射.多语言混合编程 package mai ...
- Html5-Video标签以及字幕subtitles和captions的区别
<video id="mainvideo" src="video.mp4" type="video/mp4"controls auto ...