model/view 结构
概述
The model communicates with a source of data, providing an interface for the other components in the architecture. The nature of the communication depends on the type of data source, and the way the model is implemented.The view obtains model indexes from the model; these are references to items of data. By supplying model indexes to the model, the view can retrieve items of data from the data source. In standard views, a delegate renders the items of data. When an item is edited, the delegate communicates with the model directly using model indexes.
model 用来和数据通信,为View,delegate 提供接口。 model和数据通信的方式 和数据源的类型以及model的实现方式有关。view 从 model 获取 model index。这些index 是 数据项的引用。 通过把model indexes提供给model, view可以从数据源中获取数据 。在标准的views中,delegte 对数据项进行渲染。当某个数据项被选中,delgate通过model index 直接与model交流。
Generally, the model/view classes can be separated into the three groups described above: models, views, and delegates. Each of these components is defined by abstract classes that provide common interfaces and, in some cases, default implementations of features. Abstract classes are meant to be subclassed in order to provide the full set of functionality expected by other components; this also allows specialized components to be written.
这个结构分为三个部分,models,views,delegates. 每个部分都被定义为抽象类,用来提供高一些通用的接口。在一些情况下,有默认实现方式。
三者的信息传递 通过 槽机制(signal/slots)
Models, views, and delegates communicate with each other using signals and slots:
1. Signals from the model inform the view about changes to the data held by the data source.
2. Signals from the view provide information about the user’s interaction with the items being displayed.
3. Signals from the delegate are used during editing to tell the model and view about the state of the editor.
来自model 的信号告知view 数据源数据的变化
来自 view 的信号用户和展示出的项目的交互信息
来自delegate 的信号被用来通知model,view editor的状态(在被选中的时候)
Models
基类: QAbstractItemModel。 所有的类都以此为基础。 该类定了一个接口用于views和delegates 与data的通道。
另外:QAbstractListModel,QAbstractTableModel为 list,Table 提供各类很好的方法。还有一些设定好的类:
QStringListModel,QStandardItemModel,QFileSystemModel,QSqlQueryModel,QSqlTableModel,QSqlReleationTableModel. 也可以继承前面的三个基类,来自定义model.
Qt提供了两个标准的models:QStandardItemModel和QDirModel。QStandardItemModel是一个多用途的model,可用于表示list,table,tree views所需要的各种不同的数据结构。这个model也持有数据。QDirModel维护相关的目录内容的信息,它本身不持有数据,仅是对本地文件系统中的文件与目录的描述。QDirModel是一个现成的model,很容易进行配置以用于现存的数据,使用这个model,可以很好地展示如何给一个现成的view设定model,研究如何用model indexes来操纵数据。
Views
基类: QAbstractItemView.
另外Complete implementations are provided for different kinds of views:
QListView displays a list of items,
QTableView displays data from a model in a table,
QTreeView shows model items of data in a hierarchical list.
Delegates
基类:QAbstractItemDelegate
默认的delegate 接口是QStyleItemDelegate。他和 QItemDelegate 是相互独立可选择的。
两者区别在于: QStyledItemDelegate uses the current style to paint its items。 文档上说 推荐使用QStyledItemDelegate
例子
QSplitter *splitter = new QSplitter;
//初始化一个已经存在model
QFileSystemModel *model = new QFileSystemModel;
model->setRootPath(QDir::currentPath());
//初始化一个 treeView
QTreeView *tree = new QTreeView(splitter);
//让tree在model中展示
tree->setModel(model);
//设置model index
tree->setRootIndex(model->index(QDir::currentPath()));
//index() 用来返回一个model index
QListView *list = new QListView(splitter);
list->setModel(model);
tree->setRootIndex(model->index(QDir::currentPath()));
splitter->setWindowTitle("Differences");
splitter->show();
model index
作用: 保证数据表示 和获得主句的通道 分离。通过model index,可以引用model中的数据项,Views和delegates都使用indexes来访问数据项,然后再显示出来。
因此,只有model需要了解如何获取数据,被model管理的数据类型可以非常广泛地被定义。Model indexes包含一个指向创建它们的model的指针,这会在配合多个model工作时避免混乱。
QAbstractItemModel *model = index.model();
model indexes提供了对一项数据信息的临时引用,通过它可以访问或是修改model中的数据。既然model有时会重新组织内部的数据结构,这时model indexes便会失效,因此不应该保存临时的model indexes。假如需要一个对数据信息的长期的引用,那么应该创建一个persistent model index。这个引用会保持更新。临时的model indexes由QModelIndex提供,而具有持久能力的model indexes则由QPersistentModelIndex提供。在获取对应一个数据项的model index时,需要考虑有关于model的三个属性:行数,列数,父项的model index。
QFileSystemModel *model = new QFileSystemModel;
QModelIndex parentIndex = model->index(QDir::currentPath());
int numRows = model->rowCount();
qDebug()<<"munRows"<<numRows;
for (int row = 0; row < numRows ; row ++){
QModelIndex index = model->index(row,0,parentIndex);
QString text = model->data(index,Qt::DisplayRole).toString();
qDebug()<<text;
}
- the dimensions of a model can be found using rowCount() and columnCount(). These functions generally require a parent model index to be specified.
- Model indexes are used to access items in the model. The row, column, and parent model index are needed to specify the item.
- To access top-level items in a model, specify a null model index as the parent index with QModelIndex().
- Items contain data for different roles. To obtain the data for a particular role, both the model index and the role must be supplied to the model.