Qt4.6.2文档翻译:模型/视图编程介绍
•. 模型/视图架构
•. 模型
•. 视图
•. 代表( Delegates )
•. 排序
•. 便利类
•. 模型/视图组件
Qt 4 引入了一组新的项目( item )视图类,它们使用模型/视图架构来管理 数据 与 数据展示给用户的方式 之 间的关系。这个架构所引入的功能的分离给予开发者更大的灵活性来定义项目的展示形式,并且提供一个标准的模型接口以允许配合现有的项目视图使用多种类型的 数据源。在这个文档中,我们给出模型/视图模式的一个简单介绍,概述相关的概念,并且描述项目视图系统的架构。这个架构中的每一个组件都被解说,并且给出 示例来展示系统所提供的类是如何使用的。
模型-视图-控制器( MVC )是一个起源于 Smalltalk 的设计模式,它经常在构建用户界面的时候被使用。在设计模式( Design Patterns )中, Gamma et al. 写道:
MVC由三种对象组成。模型是应用程序对象,视图是它的屏幕展示,控制器定义了用户界面对用户输入进行响应的方式。在MVC之前,用户界面的设计倾向于将这些对象混在一起。MVC将它们分离以增加灵活性和重用性。
如果视图和控制器对象被合并,那么结果就是模型/视图架构。这仍然将数据存储的方式与数据 展现给用户的方式分离开了,但是提供了一个基于简单的原则的更简单的框架。这种分离使得在多个不同的视图中展示同一个数据成为可能,并且可以在不更改底层 数据结构的情况下实现新的视图类型。为了允许灵活地处理用户输入,我们引入了 代表 的概念。在这个框架中加入代表的好处是,允许自定义展示数据和编辑数据的方式。
|
模型/视图架构 模型与一个数据源通信,为架构中的其它组件提供一个 接口 。通信的性质取决于数据源的种类和模型的实现方式。 视图从模型取得 模型索引 ;这些是指向数据项目的引用。通过对模型使用模型索引,视图可以从数据源取得数据项目。 在标准的视图中,一个 代表 渲染数据项目。当一个项目被编辑后,代表直接使用模型索引与模型通信。 |
一般地,模型/视图类可以分成以上描述的三种类型:模型,视图和代表。每种类型的组件是被 抽象 类定义的,抽象类提供共用的接口,在某些情况下也提供一些功能的默认实现。抽象类是用来被子类化以提供其它组件所预期的完整功能的;这也使得可以编写特殊的组件。 模型,视图和代表互相之间使用 信号 和 信号槽 来通信:
•. 来自模型的信号告知视图关于数据源的数据发生变化的信息。
•. 来自视图的信号提供关于用户对于显示的项目进行交互的信息。
•. 来自代表的信号是在编辑时使用的,用来告知模型和视图关于编辑器的状态的信息。
所有的项目模型都是基于 QAbstractItemModel 类的。这个类定义一个被视图和代表用来访问数据的接口。数据自身不需要被储存在模型中;它可以被保存在一个数据结构中,或者是由一个独立的类提供的仓库、一个文件、一个数据库或者其它的应用程序组件中。
围绕着模型的基本概念是在 模型类 一节中描述的。
QabstractItemModel 提供到数据的接口,该接口足够灵活,可以应对用来展示表格型、列表型和树型数据的视图。然而,在实现用来处理列表和表格型数据结构的模型时, QAbstractListModel 和 QAbstractTableModel 是更好的开始点, 因为它们对公共函数提供了适当的默认实现。它们中的每个类都能被子类化,以提供用来支持特殊种类的列表和表格的模型。
将模型子类化的过程在 创建新模型 一节中描述。
Qt 提供一些现成的模型,它们可以用来处理数据项目:
•. QStringListModel 用来存储一个由 QString 项目组成的简单的列表。
•. QStandardItemModel 管理更复杂的由项目组成的树型结构,每个项目都可以包含任意的数据。
•. QFileSystemModel 提供关于本地文件系统中的文件和目录的信息。
•. QSqlQueryModel , QSqlTableModel , 和 QSqlRelationalTableModel 是用来以模型/视图模式来访问数据库的。
如果这些标准的模型不能满足你的要求,你可以子类化 QAbstractItemModel , QAbstractListModel ,或 QAbstractTableModel 来创建你自己定义的模型。
为不同类型的视图提供了完整的实现: QListView 显示一个由项目组成的列表, QTableView 显示来自于一个表格中的模型的数据, QTreeView 显示一个层次化的列表中的数据的项目模型。这些类中的每一个都是基于 QAbstractItemView 这个虚基类( abstract base class )的。尽管这些类是现成的可以直接使用的实现,它们仍然可以被子类化以提供自定义的视图。
可用的视图可在 视图类 一节查看。
QAbstractItemDelegate 是模型/视图框架中的代表的基类。从 Qt 4.4 开始,默认的代表实现由 QStyledItemDelegate 提供,而这个被用来作为 Qt 的标准视图的默认代表。然而, QStyledItemDelegate 和 QItemDelegate 是无关的两种用来绘制和为视图中的项目提供编辑器的实现方式。它们之间的区别在于, QStyledItemDelegate 使用当前的样式来绘制它的项目。因此,我们建议在利用 Qt 样式单的时候使用 QStyledItemDelegate ,或者在实现自定义的代表时使用 QStyledItemDelegate 作为基类。
代表在 代表类 一节描述。
在模型/视图架构中,有两种方法可用来进行排序;选择哪种方法取决于你的底层模型。
如果你的模型可以被排序,也就是说,如果它实现了 QAbstractItemModel::sort () 函数,那么 QTableView 和 QTreeView 都提供一个允许以编程的方式将模型进行排序的 API 。另外,你可以通过将 QHeaderView::sortIndicatorChanged () 信号分别连接到 QTableView::sortByColumn () 信号槽或者 QTreeView::sortByColumn () 信号槽,来启用交互式排序(也就是说,允许用户通过点击视图的表头来对数据进行排序)。
另一种实现方式,如果你的模型没有提供要求的接口,或者你想要使用一个列表视图来展示你的数据,那么使用一个代理模型,以在展示视图中的数据之前转换模型的结构。这在 代理模型 一节做了具体的描述。
有一些从标准视图类派生的便利类,以为依赖于 Qt 的基于项目的项目视图和表格类的应用程序提供便利。它们倾向于被子类化,但是也简单地存在以提供一个与等价的 Qt 3 中的类相似的接口。
这些类的例子包括 QListWidget , QTreeWidget 和 QTableWidget ;这些类提供与 Qt 3 中的 QListBox , QListView 和 QTable 类相似的行为。
这些类的灵活性比不上视图类,而且不能用于任意类型的模型。我们建议你在处理项目视图中的数据时使用模型/视图方法,除非你强烈地需要一组基于项目的类。
如果你希望利用模型/视图方法提供的优点,同时又使用一个基于项目的接口,那么考虑一下与 QStandardItemModel 一起使用像 QListView , QTableView 和 QTreeView 这些视图类。
接下来的一些小节描述 Qt 中使用模型/视图设计模式的方式。每个小节提供一个关于使用的示例,紧接着的一个小节展示如何创建你的自定义组件。
Your opinionsHxLauncher: Launch Android applications by voice commands