lesson12-Model/View结构

简介: 一、model/view介绍 1、来源 Qt中的model/view结构由smalltalk公司的MVC结构发展而来。MVC有三种对象组成:model、view、contoller: model表示数据集,每种数据都有自己的数据模型,不管底层的数据集是什么样子,model提供给视图的API都是相同的 view视图是面向用户的那些数据。
一、model/view介绍
1、来源
Qt中的model/view结构由smalltalk公司的MVC结构发展而来。MVC有三种对象组成:model、view、contoller:
model表示数据集,每种数据都有自己的数据模型,不管底层的数据集是什么样子,model提供给视图的API都是相同的
view视图是面向用户的那些数据。同一时间,对于大数据集只有少量的数据对用户是可见的,而这部分可见的数据就是视图请求的。
controller是用户和视图之间的媒介,它把用户的操作转换为对数据的浏览或者编辑请求。

MVC的基本思路就是将数据的存储和表示分开分离。

2、Qt中的model/view
Qt中的model/view结构和MVC的基本思路一样,只是讲view和controller结合在一起。
model负责底层数据的存储,向上提供API。
view负责上层数据的显示,不同的视图可以呈现给不同的用户。

这种数据的存储和显示分离的方式,使得在不同的view上可以显示相同的数据,而改变view时对底层的数据没有影响
Qt中的model/view添加的代理delegate,model可以直接给view发送数据,或者经过delegate修改之后在发送给view。
将模型与视图分离之后,在处理大数据集的时候,可以提高效率;当底层数据存储方式改变之后,只需要修改model,而不需要许改view 


3、三个组件通信
在Qt的model/view中有3个组件,他们之间的通信采用信号和槽机制
model发出的信号通知view数据源发生了变化
view发出的信号提供了显示的数据项与用户交互的信息
delegate发出的信号用于在编辑时通知model和view当前的编辑状态

model为view和delegate提供了标准的接口来访问数据,这些接口在QAbstractItemModel中定义,这个类是所有model的基类;同理QAbstractItemView是所有view的基类。


 二、 使用model/view
1、Qt提供的model
QAbstractItemModel是所有model的基类,数据不需要存储在model中,可以存储在其他的地方。model为数据提供一个接口,它非常的灵活,对于不同的view基本满足要求

QAbstractItemModel下面又有子类QAbstractListModel、QAbstractTableModel、QStandardItemModel等等。如果要实现的model是基于list类型的数据结构那么你应该继承自QAbstractListModel,如果要实现的model是基于table类型的数据结构,那么你应该继承QAbstractTableModel。

Qt提供了一些可以直接使用的model:
QStringListModel存储简单的QString列表
QDirModel提供本地系统中的文件和目录信息
QStandardItemModel管理复杂的树形结构数据
QSqlQueryModel、QSqlTableModel用来访问数据库

Qt中还有3个经常使用的view:
QListView、QTreeView、QTableView

同一个model可以用不同的view显示出来
QDirModel model;
QListView list;
QTreeView tree;
QTableView table;
list.setModel(&model);
tree.setModel(&model);
table.setModel(&model);


 
2、model index
不管底层的数据如何显示,在model中Qt的数据会有以下3种显示方式


view使用index来访问model中的数据项,从来不用关心底层的数据如何存储。一个model可以作为一个简单的表来访问,数据项由行和列定位,同时还应该提供父项的索引:
QModelIndex index=model->index(row,col,parentIndex);
当提供的父项无效时,系统会默认为顶级父项

3、data
有了index,我们就可以通过data方法获取数据:
QVariant value = model->data(index, role);


4、role
model中的数据可以作为角色来使用,为不同的环境提供不同的数据。角色决定了数据如何在view中显示,角色在Qt中是一个枚举类型





三、实例

点击(此处)折叠或打开

  1. #include QApplication>
  2. #include QDirModel>
  3. #include QTreeView>
  4. #include QListView>
  5. #include QTableView>
  6. #include QSplitter>
  7. #include QtGui>

  8. int main(int argc, char *argv[])
  9. {
  10.     QApplication app(argc, argv);
  11.     
  12.     QStringList str;
  13.     str"11""22""33""44";

  14.     //model
  15.     QStringListModel *model = new QStringListModel(str);
  16.     //view
  17.     QListView list;
  18.     QTreeView tree;
  19.     QTableView table;

  20.     list.setModel(model);
  21.     table.setModel(model);
  22.     tree.setModel(model);

  23.     QSplitter *splitter = new QSplitter();
  24.     splitter->setOrientation(Qt::Vertical);
  25.     splitter->addWidget(&list);
  26.     splitter->addWidget(&table);
  27.     splitter->addWidget(&tree);
  28.     splitter->show();

  29.     QModelIndex ind = model->index(1,1);
  30.     QVariant value = model->data(ind, Qt::DisplayRole);
  31.     qDebug()value;

  32.     return app.exec();
  33. }








相关文章
|
4月前
|
JavaScript 前端开发 安全
Vue学习之--------内置指令的使用【v-bind、v-model、v-for、v-on、v-if 、v-else、v-show、v-text。。。】(2022/7/19)
这篇文章详细介绍了Vue中常见的内置指令,如v-bind、v-model、v-for、v-on、v-if、v-else、v-show、v-text和v-html等,并通过代码示例演示了它们的使用和效果。
Vue学习之--------内置指令的使用【v-bind、v-model、v-for、v-on、v-if 、v-else、v-show、v-text。。。】(2022/7/19)
|
7月前
|
XML 前端开发 Java
Model-View-Controller
“【5月更文挑战第28天】”
49 4
|
5月前
vue3【实用教程】v-model(含给 v-model 添加参数,绑定多个 v-model ,v-model 的内置修饰符,自定义 v-model 的修饰符等)
vue3【实用教程】v-model(含给 v-model 添加参数,绑定多个 v-model ,v-model 的内置修饰符,自定义 v-model 的修饰符等)
198 0
|
7月前
|
JavaScript
v-model和:model的区别
v-model和:model的区别
247 0
|
前端开发
v-bind与v-model的区别
v-bind与v-model的区别
197 0
|
图形学
错误提示: "InfraWorks is unable to render your model" when trying to load a model
错误提示: "InfraWorks is unable to render your model" when trying to load a model
错误提示: "InfraWorks is unable to render your model" when trying to load a model
|
数据格式 JSON 前端开发
Ext6中从Component如何找到Store和Model
这个问题挺傻的,也很基础。View部分的代码 Ext.define('RUKU.view.hr.HRUserList', { extend: 'Ext.grid.Panel', xtype: 'hruserlist', // 引入store requires:[ 'RUKU.
1762 0
|
前端开发
把GEF放在ViewPart里
其实可以放在任何Composite上,当然也就可以放在视图里了。关键任务是创建GraphicalViewer、RootEditPart、EditDomain和EditPartFactory这些对象,下面的代码是我从别处拷来的,稍微修改了一下。
1126 0