模型/视图编程

Posted Respect@

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模型/视图编程相关的知识,希望对你有一定的参考价值。

模型/视图编程

Qt中的模型/视图架构用来实现大量的数据存储、处理及显示。MVC(Model-View-Controller)包括了3个组件:模型(Model)是应用对象,用来表示数据;视图(View)是模型的用户界面,用来显示数据;控制(Controller)定义了用户界面对用户输入的反应方式。委托(Delegate)用于定制数据的渲染和编辑方式。

模型

所有的模型都基于QAbstractItemModel类,该类提供了十分灵活的接口来处理各种视图,这些视图可以将数据的表现形式为表格(table)、列表(list)、树(tree)。
Qt提供了一些现成的模型来处理数据项:
QStringListModel 存储简单的QString项目列表;
QStandardItemModel管理复杂的属性结构数据项,每一个数据项可以包含任意的数据;
QFileSystemModel提供了本地文件系统中文件和目录信息;
QSqlQueryModel、QSqlTableModel和QSqlRelationTableModel用来访问数据库。
标准模型还无法满足需要时,可子类化QAbstractItemModel、QAbstractListModel或QAbstractTableModel来创建自定义的模型。
常见的3种模型为列表模型、表格模型、树模型,如下图所示:

为确保数据的表示与数据的获取相分离,Qt引入了模型索引的概念,输入和委托均可通过模型索引来请求数据并显示。只有模型需要知道怎样获取数据,被模型管理的数据类型可以被广泛的定义。模型索引包含一个指针,指向创建他们的模型,使用多个模型时可避免混淆。模型索引QModelIndex类提供对一块数据的临时引用,用来修改或检索模型中的数据,获取一个数据项的模型索引必须指定模型的3个属性:行号、列号和父项的模型索引。如:
QModelIndex index = model->index(row,column,parent);
也可通过模型指定的相关数据项对应的模型索引以及特定的角色来获取需要的类型数据,如:
QVariant value = model->data(index,role);
常用的角色类型:

常量描述
Qt::DisplayRole数据被渲染为文本(数据为QString类型)
Qt::DecorationRole数据被渲染为图标等装饰(数据为QColor,QIcon,或QPixmap类型)
Qt::EditRole数据可以在编辑器中进行编辑(数据为QString类型)
Qt::ToolTipRole数据显示在数据项的工具提示中(数据类型为QString)
Qt::StatusTipRole数据显示在状态栏中(数据为QString类型)
Qt::WhatsThisRole数据显示在数据项的“What’s This?”模式下(数据为QString类型)
Qt::SizeHintRole数据项的大小提示,将会应用到视图(数据为QSize类型)
Qt::FontRole默认代理的绘制使用的字体
Qt::TextAlignmentRole默认代理的对齐方式
Qt::BackgroundRole默认代理的背景画刷
Qt::ForegroundRole默认代理的前景画刷
Qt::CheckStateRole默认代理的检查框状态
Qt::UserRole用户自定义的数据的起始位置

视图

Qt提供了QListView、QTableView视图、QTreeView视图分别实现列表、表格与树视图效果。QListView将数据项显示为一个列表;QTableView将模型中的数据显示在一个表格中;QTreeView将模型中的数据项显示在具有层次的列表中。QTableView和QTreeView在显示项目的时候同时还可以显示标头,通过QHeaderView类实现。自定义视图类是基于QAbstractItemView抽象基类,如实现条形图,饼状图等特殊显示方式。

视图类的选择行为

常量描述
QAbstractView::SelectItems选择单个项目
QAbstractView::SelectRows只选择行
QAbstractView::SelectColumns只选择列

视图类的选择模式

常量描述
QAbstractItemView::SigleSelection当用户选择一个项目时,所有已经选择的项目将成为未选择状态,而且用户无法在已经选择的项目上单击来取消选择
QAbstractView::ContiguousSelection用户单击一个项目的同时,按Shift键,则所有当前项目和单击项目之间的项目都将被选择或取消选择
QAbstractView::ExtendedSelection具有ContiguousSelection的特性,且可按Ctrl键进行不连续选择
QAbstractView::MultiSelection用户选择一个项目时不影响其他已经选择的项目

QAbstractView::NoSelection 项目无法被选择

选择模型更新方式

QItemSelectionModel::SelectionFlags释义
QItemSelectionModel::NoUpdate不做选择
QItemSelectionModel::Clear选择被清除
QItemSelectionModel::Select选择指定索引
QItemSelectionModel::Deselect取消指定索引的选择
QItemSelectionModel::Toggle切换指定索引的选择
QItemSelectionModel::Current当前选择被更新
QItemSelectionModel::Rows索引扩展为跨行
QItemSelectionModel::Columns索引扩展为跨列
QItemSelectionModel::SelectCurrent SelectCurrent组合
QItemSelectionModel::ToggleCurrent ToggleCurrent组合
QItemSelectionModel::ClearAndSelect ClearSelect组合

委托

在模型/视图框架中,QAbstractItemDelegate是委托类的抽象基类,Qt默认的委托实现由QStyledItemDelegate类提供,这也被用作Qt标准视图的默认委托,选择 QStyledItemDelegate或QItemDelegate中其一来为视图中的项目绘制和提供编辑器。不同的是QStyledItemDelegate使用当前的样式来绘制项目,实现自定义委托建议使用QStyledItemDelegate作为基类。
Qt提供了项目试图的便捷类,这些类底层通过模型/视图框架实现。这些部件分别是QListWidget提供一个项目列表,QTreeWidget显示一个多层次的树结构,QTableWidget提供了一个以项目作为单元的表格。它们每一个类都继承了QAbstractItemView类的行为。之所以成为便捷因其用起来比较简单,使用于少量的数据的存储和显示。因没有将视图与模型分离,所以没有视图类灵活,不能和任意的模型一起使用。

以上是关于模型/视图编程的主要内容,如果未能解决你的问题,请参考以下文章

Qt 模型/视图编程设计模式是不是受限?

我可以以编程方式触发淘汰视图模型更新吗?

QT 模型/视图编程:我应该如何检索上下文菜单选项的额外数据?

具有封装/防御性编程的 MVC(模型视图控制器)

Qt入门教程数据模型篇模型/视图教程

Qt入门教程数据模型篇模型/视图教程