QT4 介绍了一系列新的 Item View 类,这些类使用Model/View结构来管理数据和数据如何呈现给用户。这种结构使程序员更加灵活的开发和定制呈现数据界面,Model/View结构提供标准的Model接口让各种数据资源都能够被存在的Item View使用。
The model/view architecture
MVC是一种源于 smalltalk的设计模式,经常用来构建应用程序界面。
MVC有3个对象构成。 Model是 Application object, View是screen presentation,Controller 定义界面对用户输入的反应(各种事件)。在MVC之前,程序员把所有的设计都放在一个类中。MVC使得代码更灵活和数据重用。
如果View和Controller对象结合起来,结果就是Mode/View结构。这种方式仍然分离了提供给用户的数据,但是提供了一个简单的框架,基于一样的标准。这种分离使得能在不同的View中展示同一个数据,实现新的View类,而不用改变底层的数据结构。为了灵活处理用户输入,我们介绍Delegate的概念,在框架中有Delegate的好处是它(Delegate)能够处理数据渲染(数据如何显示出来)和定制数据(数据能够被编辑处理,达到定制的效果)。Delegate数据渲染使用paint()方法 。创建Editor for data 使用createEditor()方法。
Model类,数据之间的通讯(数据的获得 改变等方法),为Model/View结构中其他组件提供接口(例如notifyListener()方法,告知其他组件数据已经被改变)。通讯的性质取决于数据的类型和Model的实现方式。Model中把数据按照角色分类(enum Qt::ItemDateRole),Qt::DisplayRole仅仅就是以Text的方式显示数据,其他例如Qt::FontRole决定字体。所以Model通过Qt::ItemDateRole 机制能够影响应用程序的外观。
View类从Model类中获得Model Index,Model Index就是数据项的引用。通过提供Model Index给Model,View类能够从数据源中获得数据。在标准的View类中,Delegate用来渲染数据,当一个Item被编辑时,Delegate通过Model Index直接和Model 通讯。
总的来说Model/View类能被分成3组:Models、View、Delegates。这些组件都被定义在抽象类之中,抽象类提供公有的接口,某些情况下,默认实现一些函数。抽象类意味着子类根据需要来implement这个抽象类。
Model、View、Delegate之间的相互通讯使用信号和槽机制。
Model中的信号告诉View数据源中的某数据被改变
View中的信号和用户交互信息有关(如何展示这个Item)
Delegate中的信号,在Editing中发射,告诉Model和View editor的状态。
Models
所有的Item Model类都是基于QAbstractItemModel类,这个类定义了接口,View和Delegate如何获得数据。数据本身并没有存储在Model类中,数据能够存储在单独类的数据结构中、文件、数据库、其他应用程序的组件中。
QAbstractItemModel提供了足够灵活的数据接口,以处理列表、列表、树形式表示数据的视图。然后当实现列表、表数据结构的新Model时,QAabstractListModle和QAabstractTableModel是更好的选择,因为它们提供了一些函数的默认实现。这些类每一个都可以被子类化,以提供专门类型的列表和表模型。
QT提供了一些可以被用于处理数据模型的现成模型:
1.QStringListModel 用来储存一个简单的QString列表
2.QStandardItemModel 用来管理复杂的树结构,每个树结构能包含任意数据。
3.QFileSystemModel 提供本地文件系统中文件和目录信息。
4.QSqlQueryModel,QSqlTableModel和QSqlRelationalTableModel 使用Model/View标准 来访问数据库。
Views
不同类型的视图提供了完整的实现:QListView显示列表项目,QTableView把数据显示在表格中,QTreeView显示分层的数据。这些类都是基于QAbstractItemView这个抽象基类。虽然这些类可以立即使用,但也可以被子类化提供定制的视图。
Delegates
QAbstractItemDelegate是Modie/View中Delegate的抽象基类,从Qt4.4开始默认的Delegate实现由QStyledItemDelegate提供,而且被作为Qt View的默认Delegate。QStyledItemDelegate和QItemDelegate是独立的都能使用。但是QStyledItemDelegate用当前的样式来渲染和创建Editor。所以在自定义Delegate时,建议使用QStyledItemDelegate作为基类。