模型视图基础

模型对需要查看的数据的获取以及任何存储的改变负责,不管底层模型如何,模型提供给视图的API是相同的,视图代表面向用户的那些数据,委托用户 对项的如何显示和如何编辑提供精细的控制。

通过把一个模型注册到多个视图中,可以让用户使用不同的方式查看数据以及和数据交互,视图会自动保持同步。

所有的模型都基于QAbstractItemModel,但是它本身不存储任何数据,它仅仅提供一些接口来提供视图访问数据。数据本身并不一定要存储在模型中,也可以存储在一个数据结构或者一个独立的类,文件或者数据库等其他一些组件中。要实现一个新的模型时,如果它基于列表或者表格的数据结构,那么可以继承QAbstractListModel和QAbstractTableModel类,它们为常见的功能提供了默认的实现。Qt有一些现成的模型可以使用,比如QStandardItemModel管理复杂的树形结构数据项,QFileSystemModel提供了本地文件系统中文件和目录的信息,使用如:

QFileSystemModel model;
model.setRootPath(QDir::currentPath());
QTreeView tree;
tree.setModel(&model);
tree.setRootIndex(model::index(QDir::currentPath()));

视图从模型中获得模型索引,模型用索引来表示数据项,编辑项时委托使用模型索引与模型通信,因为模型可能随时对内部进行重新组织,这样模型索引可能失效,所以不需要也不应该存储模型索引,如果需要对一块数据进行长时间的引用,则必须使用QPersistentModelIndex创建索引。要获得一个数据项的模型索引,则必须制定模型的3个属性:行号,列号和父项的模型索引

模型中的数据项可以作为各种角色在其他组件中使用,允许为不同的情况提供不同类的数据,这些标准的角色由枚举类型Qt:ItemDataRole来定义,通过为每个角色提供适当的项目数据,模型可以为视图和委托提供提示,告知数据应该怎样展示给用户,角色指出了从模型中引用哪种类型的数据,视图可以使用不同的方式来显示不同的角色。

我们可以通过继承QAbstractTableModel,创建自己的表模型,对于只读表,必须重新实现rowCount(),columnCount(),data(),在模型中一个无效的模型索引用来表示根。为了提供一个可以编辑数据的委托,必须实现createEditor(),setEditorData(),setModelData(),还要根据情况修改paint()

视图有选择行为QAbstractView::SelectionBehavior和选择模式QAbstraxtView::SelectionMode来设置用户的一些选择。在视图中被选择的项目的信息存储在一个QItemSelectionModel实例中,这样被选择项目的模型索引便保持在一个独立的模型中,与所有视图都是独立的。视图中,总是有一个当前项目和一个被选择的项目,两者是独立的两个状态,当操作选择时,可以将QItemSelectionModel看做一个项目模型中所有项目的选择状态的一个记录,一旦设置了一个选择模型,所有的项目集合都可以被选择,取消选择或者切换选择状态,要使用选择模型来选择视图中的项目,就必须制定QItemSelection和选择模式QItemSelectionModel::SelectionFlag,QItemSelection是一个项目选择块,需要指定它的左上角和右下角项目的索引,而选择模式是选择模型的更新的方式,是一个枚举类型。

委托负责交互,它通过实现paint()和sizeHint()函数来使他们可以渲染自身的内容,委托的编辑器可以通过两种方式实现,一种是使用部件来管理编辑过程,另一种是直接处理事件。

模型视图完全支持拖放,在列表,表格和树中的项目可以在视图中被拖放,数据可以作为MIME编码的数据被导入和导出,默认的,视图的拖放功能并没有被启用,如果要进行项目的拖动,就需要进行一些属性的设置。要启用项目的拖动,要将视图的dragEnable设置为true,要允许用户将内部或者外部的项目放入视图中,需要设置视图的viewport()的acceptDraops设置为true,要显示现在用户拖曳的项目将要放置的位置,需要设置showDropIndicator属性

代理模型可以将一个模型中的数据进行排序或者过滤,然后提供给视图进行显示,Qt中提供了QSortFilterProxyModel作为标准的代理模型来完成模型中数据的排序和过滤

数据-窗口映射器QDataWidgetMapper类在数据模型的一个区域和一个窗口部件间提供了一个映射,这样就可以实现在一个窗口部件上显示和编辑一个模型中的一行

猜你喜欢

转载自blog.csdn.net/weixin_38893389/article/details/80950238