当前位置: 首页>编程语言>正文

qt mvvm5层架构 qt的mvc

QT官方帮助文档中搜索:Model,找到:Model/View Programming 以及Model/View Tutorial 系列教程,当然看起来有些费劲,但却是最权威的资料。

该系列博文,内容全部来自官方手册,加上一些我自己的理解,相信大家看起来会更轻松一些。

qt mvvm5层架构 qt的mvc,qt mvvm5层架构 qt的mvc_QT,第1张

 

0、MV架构

该文章来自【暴躁的野生猿】博客,如有非法转载,请读者帮忙举报下。

MVC指的是Model、View、Control,模型视图控制三者分离的一种数据与用户交互的方式。Qt本质上实现的是MV结构,没有Control,其实MV架构已经足以应付大多数应用场景了。其优势是把数据的存储方式和视图的展示方式,给解耦了,所谓解耦,举2个例子:

(1)数据可能存储在某个类的实体中、txt文件中、数据库中、网络上、操作系统内核里(如文件系统信息)等等,而视图View要展示这些数据时,并不关心数据是存储在哪,数据的存储结构如何,因为View要展示数据时,只会跟Model索要数据。

(2)基于QT提供的Model框架,我们可以在不改变数据的情况下,更改视图的展示方式,比如对于同一组数据,可以立即展示为列表、饼图、柱状图等,甚至可以针对这同一组数据同时显示多种视图,用户从任何一个视图修改数据(如果相应的视图提供了编辑功能的话),在其他视图中都会得到同步响应。

qt mvvm5层架构 qt的mvc,qt mvvm5层架构 qt的mvc_Data_02,第2张

 MVD的通信结构,该图来自官方手册。在图中我们看到视图View是无法直接与数据Data打交道的,不论读还是写数据,必须由Model进行中转。更确切的说,由上图可见,View与Data的交互,必须经过Delegate和Model两层中转,才能得以读写。
在QT源码中,数据在Data与View之间的流转过程,是基于信号槽实现的:

  • 当Data发生变化时,Model会发出信号通知View,进行重新渲染,如上图的Model->View的箭头所示。
  • 当用户用鼠标或者键盘等在视图上动作时,View会发出信号给Delegate,用户要如何编辑数据,如上图View->Delegate箭头所示。
  • 当用户使用Delegate编辑数据时,Delegate会发信号告诉Model和View,用户编辑的结果。

 

1、模型

model “模型”的作用是:供视图读写真正的数据。

不同于上图所示的结构,Data有时候会被写在Model实体的内部,这只发生在一些简单的应用场景中,可参考我的该系列的另一篇博文,有这样的例子。即使我们把Data放到了Model内部,也仍然要遵循上述这种数据流转架构。

学习这些概念的最终目的是为了写程序,这里还是要讲一下QT,所有的模型类的祖宗都是QAbstractItemModel,通过继承他,我们可以写出能够适应各种视图的模型。不过如果你想把这个模型展示为列表、表格、树,这三种情形之一时,没必要继承QAbstractItemModel,因为QT提供了更方便的类QAbstractListModelQAbstractTableModel类供我们使用,这两个类也是继承的QAbstractItemModel,只是已经替我们实现了必要的虚函数,可参考该系列我其他的博文,看看这两个类是如何简化我们的编程工作量的。

不仅如此,QT还再次继承类QAbstractListModelQAbstractTableModel类,提供了比这俩更方便的类:

  • QStringListModel 字符串列表模型;
  • QStandardItemModel 用户更加复杂的树形机构,内容可以是任意数据
  • QFileSystemModel 这个可以直接帮我们取出操作系统文件模型,供我们将其展示为列表、表格、树等,例如windows资源管理器那种树形结构。
  • QSqlQueryModel, QSqlTableModel, QSqlRelationalTableModel 用于访问数据库

这些类很方便(所谓“方便”,其实就是说,程序员可以少写几个函数)的同时,也会丧失灵活性,毫无疑问,最灵活的类是祖宗QAbstractItemModel,继承它可以实现model的所有功能,也是用起来最麻烦的类。

qt mvvm5层架构 qt的mvc,qt mvvm5层架构 qt的mvc_QT_03,第3张

上图是直接把QFileSystemModel的一个对象,直接分别绑定到列表视图、树形视图、表格视图时的效果,简直方便。

QFileSystemModel *fModel = new QFileSystemModel();
    fModel->setRootPath("C:\");

    QTreeView *treeView = new QTreeView();
    treeView->setModel(fModel);
    treeView->show();

    QTableView *tableView = new QTableView();
    tableView->setModel(fModel);
    tableView->show();

 

2、委托Delegate

delegate “委托”,这个词听起来相当令人困惑,有些教程中也会将其翻译为“代理”,从字面上很难理解他到底是干嘛的,这只能死记硬背了。delegate的作用是:为指定索引的数据,提供一种自定义的展示方式与编辑方式,仅此而已。

QAbstractItemDelegate是所有delegate的祖宗类,QT内置了它的2个子类:QStyledItemDelegateQItemDelegate,他俩的区别在于QStyledItemDelegate使用当前样式进行绘制,且支持样式表。QT官方推荐,自定义委托时,要使用QStyledItemDelegate,不推荐QItemDelegate。

 

 

 

 


https://www.xamrdz.com/lan/5jg1960303.html

相关文章: