模型/视图介绍
Qt包含了一组item view类,它们使用模型/视图架构来管理数据之间的关系以及呈现给用户的方式。该体系结构引入的功能分离,为开发人员提供了更大的灵活性来定制项目的表示,并提供了一个标准的模型接口,以允许广泛的数据源与现有项目视图一起使用。
模型/视图结构
模型-视图-控制器(Model-View-Controller, MVC)是一种源自Smalltalk的设计模式,经常用于构建用户界面。在《设计模式》一书中,Gamma等人写道:
MVC由三种对象组成。模型是应用程序对象,视图是它的屏幕显示,控制器定义了用户界面对用户输入的反应方式。在使用MVC之前,用户界面设计倾向于将这些对象放在一起。MVC将它们解耦以提高灵活性和重用性。
如果视图和控制器对象被组合,结果就是模型/视图架构。将数据的存储方式和呈现给用户的方式分开,使得可以在多个不同的视图中显示相同的数据,并实现新的视图类型,而无需更改底层数据结构。为了灵活地处理用户输入,引入了委托的概念。在这个框架中使用委托的好处是,它允许自定义数据项的渲染和编辑方式。
上图,模型与数据源进行通信,为结构中的其他组件提供接口。通信的性质取决于数据源的类型以及模型的实现方式;
视图从模型中获取模型索引;这些是对数据项的引用。通过向模型提供模型索引,视图可以从数据源检索数据项。
在标准视图中,委托渲染数据项。当一个项目被编辑时,委托使用模型索引直接与模型通信。
总的来说,模型/视图类可以分为上面描述的三组:模型、视图和委托。每个组件都由提供公共接口的抽象类定义,在某些情况下,还提供功能的默认实现。抽象类旨在被子类化,以便提供其他组件所期望的全套功能;这也允许编写专用组件。
模型、视图和委托使用信号(signal)和槽(slot)相互通信:
来自模型的信号通知视图关于数据源所持有的数据的更改。
来自视图的信号提供了关于用户与正在显示的项目交互的信息。
来自委托的信号在编辑过程中用于告诉模型和视图关于编辑器的状态。
模型
所有item模型都基于QAbstractItemModel类。
QAbstractItemModel类提供了一个数据接口,它可以处理以表、列表和树的形式表示数据的视图,视图和委托使用该接口访问数据。如果是列表和类似表格的数据结构实现新模型时,可以用QAbstractListModel和QAbstractTableModel类,因为它们提供了通用函数的适当默认实现。这些类都可以子类化,以提供支持特定类型列表和表的模型。
注:数据本身并不一定要存储在模型中;它可以保存在由单独的类、文件、数据库或其他应用程序组件提供的数据结构或存储库中。
Qt提供了一些现成的模型来处理数据项:
QStringListModel用于存储一个简单的QString元素列表。
QStandardItemModel管理更复杂的项目树结构,每个项目可以包含任意数据。
QFileSystemModel提供了关于本地文件系统中的文件和目录的信息。
QSqlQueryModel、qsqlltablemodel和QSqlRelationalTableModel按模型/视图约定访问数据库。
除了以上的标准模型,还可以子类化QAbstractListModel, QAbstractListModel或QAbstractTableModel来创建自己的自定义模型。
视图
为不同类型的视图提供了完整的实现:QListView显示项目列表,QTableView显示表中来自模型的数据,QTreeView显示分层列表中的数据模型项。这些类都基于QAbstractItemView抽象基类。虽然这些类是现成的实现,但它们也可以子类化以提供自定义视图。
代理
QAbstractItemDelegate是模型/视图框架中代理的抽象基类。默认的委托实现由QStyledItemDelegate提供,它被Qt的标准视图用作默认委托。但是,QStyledItemDelegate和QItemDelegate是绘图的独立替代方案,并为视图中的项目提供编辑器。它们之间的区别在于,QStyledItemDelegate使用当前样式来绘制它的项。因此,在实现自定义委托或使用Qt样式表时,我们建议使用QStyledItemDelegate作为基类。
排序
在模型/视图架构中有两种排序方法;选择哪种方法取决于你的基础模型。
如果你的模型是可排序的,即如果它重新实现了QAbstractItemModel::sort()函数,QTableView和QTreeView都提供了一个API,允许你以编程方式对模型数据进行排序。此外,还可以启用交互式排序(即允许用户通过单击视图的标题对数据进行排序),通过分别将QHeaderView::sortIndicatorChanged()信号连接到QTableView::sortByColumn()插槽或QTreeView::sortByColumn()插槽。
另一种方法是,如果你的模型没有所需的接口,或者你想使用列表视图来显示数据,则在视图中显示数据之前,使用代理模型来转换模型的结构。这在代理模型一节中有详细介绍。
方便类
为了让依赖于Qt基于item的item view和table类的应用程序受益,许多便利类都派生自标准视图类。它们不打算被子类化。
这些类的例子包括QListWidget、QTreeWidget和QTableWidget。
这些类不如视图类灵活,不能与任意模型一起使用。建议你使用model/view方法来处理item视图中的数据,除非你非常需要一组基于item的类。
如果你想利用模型/视图方法提供的特性,同时仍然使用基于项的接口,可以考虑使用视图类,例如QListView、QTableView和QTreeView与QStandardItemModel。
标签:委托,提供,模型,介绍,item,视图,使用 From: https://blog.51cto.com/u_16324960/8068049