【转】Qt之模型/视图
【本文转自】http://blog.sina.com.cn/s/blog_a6fb6cc90101hh20.html 作者: 一去丶二三里
关于Qt中MVC的介绍与使用,助手中有一节模型/视图编程(Model/View Programming)讲解的很清晰。
- 模型:应用程序对象。
- 视图:屏幕演示。
- 控制器:定义了用户界面响应用户输入的方式。
- 模型的信号:通知视图关于改变由数据源保持的数据。
- 视图的信号:提供了关于用户交互显示的项目信息。
- 委托的信号:当编辑时告诉模型和视图编辑器的状态。
- QStringListModel:用于存储简单的QString的列表项。
- QStandardItemModel:管理更复杂的树结构件,其中每一个项目可以包含任意数据。
- QFileSystemModel:提供有关本地文件系统的文件和目录信息。
- QSqlQueryModel、QSqlTableModel、QSqlRelationalTableModel:使用模型/视图约定来访问数据库。
如果这些标准模型不能满足要求,则可以继承化QAbstractItemModel、QAbstractListModel或QAbstractTableModel来创建自定义模型。
代码如下:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QSplitter *splitter = new QSplitter;
QFileSystemModel *model = new QFileSystemModel;
model->setRootPath(QDir::currentPath());
QTreeView *tree = new QTreeView(splitter);
tree->setModel(model);
tree->setRootIndex(model->index(QDir::currentPath()));
QListView *list = new QListView(splitter);
list->setModel(model);
list->setRootIndex(model->index(QDir::currentPath()));
splitter->setWindowTitle("Two views onto the same file system model");
splitter->show();
return app.exec();
}
上面的例子中,我们忽略提及如何处理选择的项目。下面将详细讲述在视图中处理所选的项目。
基本概念
在模型/视图结构中,模型提供了视图与委托访问数据的标准接口。在Qt中,标准的接口由QAbstractItemModel类定义。无论多么数据项被存储在任何底层的数据结构中,QAbstractItemModel的所有子类所代表的数据作为包含视图项的分层结构。视图使用这个约定来访问模型中的数据项,但并不限制将该信息传达给用户的方式。
Model indexes
为确保数据被分开被访问,模型索引的概念被引入。可以通过模型索引来获得每条信息。视图与委托使用这些索引来请求显示的数据项。
因此,模型只需要知道如何获取数据,并通过模型管理的数据的类型可以被相当普遍定义。型号索引包含一个指向创建它们的模型的指针,在处理多个模型时可以防止混乱。
QAbstractItemModel *model = index.model();
模型索引提供临时参考信息,并且可以用于通过模型来检索或修改数据。由于模型可能重组其内部结构,模型的索引可能会变得无效,不宜存储。如果需要长期参考一条信息,必须创建一个持久性模型索引。这为模型保持最新信息提供了一个参考。临时模型索引由QModelIndex类提供,持久性模型索引由QPersistentModelIndex类提供。
取得对应于数据项的模型索引,模型中必须制定三个属性:一个行号、一个列号,以及父项的模型索引。
行和列
在最基本的形式中,模型可以被一个简单的表访问,表项位于行号和列号,这并不意味着底层数据存储在数据结构中,使用行号和列号只是一个惯例,以允许组件相互通信。我们可以通过指定行号和列号的模型索引有关的任何特定信息,通过下面的方式得到项目的索引:
QModelIndex index = model->index(row, column, ...);
模型提供的接口简单,单级的数据结构如列表和表格不需要提供任何其他信息。但是,正如上面的代码所示,当获得一个模型索引时,我们需要提供更多的信息。
行和列
图中显示了一个基本的表模型,其中的每个项目的位置由一对行号和列号表示。我们通过模型索引(一个项目数据)行号和列号来获取。
QModelIndex indexA = model->index(0, 0, QModelIndex());
QModelIndex indexB = model->index(1, 1, QModelIndex());
QModelIndex indexC = model->index(2, 1, QModelIndex());
父节点
由模型提供的类似于表的接口给数据项是理想的当在表格或列表视图中使用数据,行号和列号准确地映射到视图显示项目的方式。然而,结构,如树视图需要更模型为项目暴露一个更灵活的接口。因此,每个项目也可以是另一个表的父项,大致相同的方式,在一个树视图中的顶级项目可以包含另一个列表项。
当请求的一个模型项的索引时,必须提供有关该项目的父项目的一些信息。在模型外,指定一个项目的唯一途径是通过一个模型索引,所以父模型索引也必须如下给出:
QModelIndex index = model->index(row, column, parent);
父项,行和列
该图显示了一个树模型,其中每个项目都依赖于由一个父项,一个行号和一个列号。
项目的“A”和“C”表示模型顶层的兄弟姐妹:
项目“A”有很多孩子,可以通过如下方式由“A”索引得到“B”索引:
QModelIndex indexB = model->index(1, 0, indexA);
QModelIndex indexA = model->index(0, 0, QModelIndex());
QModelIndex indexC = model->index(2, 1, QModelIndex());
项目角色
模型中的项目可以为其他组件演绎不同的角色,允许为不同的情况提供不同类型的数据。例如,Qt::DisplayRole可以在用于访问视图中被显示为文本的字符串。通常情况下,包含数据的项目用于若干不同的角色,且标准角色被Qt::ItemDataRole定义。
我们可以通过模型索引传递给相应的项目向模型请求项目数据,并通过指定一个角色来获取想要的数据类型,如下:
QVariant value = model->data(index, role);
数据类型被称为模型的角色指示器。视图可以以不同的方式显示角色,因此,为每个角色提供相应的信息非常重要。
项目数据最常见的用途是覆盖在Qt::ItemDataRole中定义的标准角色。通过为每个角色提供相应的项目数据,模型可以为视图和委托提供有关项目应如何呈现给用户的指示,不同的视图可以根据需要来解释或忽略此信息。此外,也可以为应用程序的特定目的而定义附加的角色。
使用模型索引
为了演示如何将数据从一个模型中进行检索,使用模型索引,我们创建了一个QFileSystemModel,在窗体上没有视图以及显示文件和目录的名称。虽然这并不是使用模型的正常方式,它表明模型在处理模型索引上的约定。
我们用以下述方式构建了一个文件系统模型:
QFileSystemModel *model = new QFileSystemModel;
QModelIndex parentIndex = model->index(QDir::currentPath());
int numRows = model->rowCount(parentIndex);
在这种情况下,我们设置了一个默认QFileSystemModel,由该模型使用index()的特定实现来获取父索引,使用rowCount()函数来计算行号。
为简单起见,我们只关心模型中的第一列中的项目。我们检查每一行,依次获取每一行中的第一个项目的模型索引,以及读出所存储在该模型项目中的数据。
for (int row = 0; row <<span style=" color:#c0c0c0;"> numRows; ++row) {
QModelIndex index = model->index(row, 0, parentIndex);
为了获得一个模型索引,我们指定了行号、列号(第一列为零),以及所有我们想要的项目的父项目的模型索引。每个项目中的文本检索可以使用模型的data()函数来获取。我们指定了模型索引和Qt::DisplayRole来获取数据项中的字符串。
QString text = model->data(index, Qt::DisplayRole).toString();
// Display the text in a widget.
}
使用模型
我们创建一个字符串列表模型作为例子,设置一些数据,并构造一个视图来显示模型的内容。这都可以在一个单一的函数执行:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QStringList numbers;
numbers << "One" << "Two" << "Three" << "Four" << "Five";
请注意,QStringListModel被声明为一个QAbstractItemModel。这使我们能够为模型使用抽象接口,并确保代码仍然有效,即使我们使用不同的模型替换了字符串列表模型。
由而QListView提供的列表视图足以展示字符串列表模型中的项目。我们构建视图,并设置模型可以使用下面代码:
QAbstractItemModel *model = new QStringListModel(numbers);
QListView *view = new QListView;
view->setModel(model);
视图正常显示方式
view->show();
return app.exec();
}
视图展现模型的内容,通过模型的接口访问数据。当用户试图编辑一个项目时,视图使用缺省代表提供一个编辑器部件。
QTableView *firstTableView = new QTableView;
QTableView *secondTableView = new QTableView;
firstTableView->setModel(model);
secondTableView->setModel(model);
在模型/视图框架中使用信号和槽是指更改模型可以传递给所有相连的视图,以确保始终可以访问相同的数据,而不管所使用的视图。
上面的图显示了统一模型的两种不同的视图,每个都包含了一些选定的项目。尽管模型中的数据在视图显示一致,每个视图维护它自己的内部选择模型。这在某些情况下有用,但对于许多应用来说,则需要一个共享的选择模型。
视图共享选择
虽然视图类提供自己的默认选择模型很方便,但当我们使用多个视图到同一个模型时,通常需要所有的模型数据和用户的选择在所有视图显示一致。由于视图类允许其内部选择模型进行更换,那么可以使用如下方式实现视图之间的统一:
secondTableView->setSelectionModel(firstTableView->selectionModel());
第二个视图给出了第一个视图的选择模型。这两种视图现在在同一个选择模型进行操作,保持了数据和所选项目的同步。
【转】Qt之模型/视图的更多相关文章
- Qt之模型/视图(自定义风格)
Qt之模型/视图(自定义风格) 关于自定义风格是针对视图与委托而言的,使用事件与QSS都可以进行处理,今天关于美化的细节讲解一下. 先看下图: 先撇开界面的美观性(萝卜青菜,各有所爱),就现有的这些风 ...
- Qt之模型/视图(自定义进度条)
简述 在之前的章节中分享过关于QHeaderView表头排序.添加复选框等内容,相信大家模型/视图.自定义风格有了一定的了解,下面我们来分享一个更常用的内容-自定义进度条. 实现方式: 从QAbstr ...
- QT MVC 模型/视图
1. 模型视图实例一, QFileSystemModel QTreeView ,model/view示例. #include <QApplication> #include <QF ...
- Qt之模型/视图(实时更新数据)
上两节简单介绍了Qt中对于模型/视图的编程,大部分助手里说的很清楚了,现在就开始实战部分吧! 在实际应用中,视图展示的数据往往并非一成不变的,那么如何实时更新成了一个很重要的问题!功能:(1)添加委托 ...
- Qt之模型/视图(委托)
概念 不同于模型 - 视图 - 控制器模式,模型/视图设计不包括用于管理与用户交互的一个完全独立的组件.一般情况,视图负责将模型数据呈现给用户以及处理用户输入.为了输入更加具有灵活性,则由委托来执行交 ...
- Qt之模型/视图(委托)
# -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' from PyQt4.Qt import * from PyQt4. ...
- Qt MVC(模型-视图-代理)
实习刚才是一段时间,公司这边就要求熟悉这个mvc.一般开始都是用tableview,前面的blog我都是使用listview居多,并且相对delegate这个使用的多余model.接下来说下model ...
- Qt之模型/视图(自定义按钮)
简述 衍伸前面的章节,我们对QTableView实现了数据显示.自定义排序.显示复选框.进度条等功能的实现,本节主要针对自定义按钮进行讲解,这节过后,也希望大家对自定义有更深入的了解,在以后的功能开发 ...
- Qt 之模型/视图(自定义按钮)
https://blog.csdn.net/liang19890820/article/details/50974059 简述 衍伸前面的章节,我们对QTableView实现了数据显示.自定义排序.显 ...
随机推荐
- Solr In Action 笔记(2) 之 评分机制(相似性计算)
Solr In Action 笔记(2) 之评分机制(相似性计算) 1 简述 我们对搜索引擎进行查询时候,很少会有人进行翻页操作.这就要求我们对索引的内容提取具有高度的匹配性,这就搜索引擎文档的相似性 ...
- JAVA基础(1)之hashCode()
JAVA基础(1)之hashCode() 看到一篇关于hashCode的文章(),写的很详细明白,瞬间有种恍然大悟的感觉,所以特地转过来.原文:http://blog.csdn.net/fenglib ...
- Regularized Linear Regression with scikit-learn
Regularized Linear Regression with scikit-learn Earlier we covered Ordinary Least Squares regression ...
- BROCADE 300和MD3200扩展柜FC SAN,截图
这表示俺玩过,其实,这个光交换机在只有一个共享存储的情况下,可用可不用. FC BROCADE只是为了方便后期扩展. FC SAN之类的识别不靠IP,因为不是IP SAN嘛.但也是自己的识别体系.
- 使用Java Applet在客户端解压缩,以及使用证书的意义
以前解压缩是用Java Applet在客户端解压缩,而且用户不知道这回事.但是现在Chrome不支持NP API了,所以不得不把Java去掉,然后在服务器里解压缩.风险在于,解压缩以后,传输到客户端的 ...
- 前端工程师和web工程师的差异
摘自园内一篇文章关于web工程师的思考,比较认同其中的一些观点 前端工程师知识结构: 精通: xhtml,css,JavaScript 熟悉:一种后端程序语言( ...
- (转载)PHP substr(),mb_substr()及mb_strcut的区别和用法
(转载)http://blog.csdn.net/alongken2005/article/details/7098506 PHP substr()函数可以 分割文字,但要分割的文字如果包括中文字符往 ...
- windows7中的“mklink命令” 转
从 Vista 以后,微软将用户文件和用户的软件配置( AppData ) 明确划分开,并且全部存放在使用者的用户目录下. Linux早已这样做了,并且在Linux中可将 home 挂载为独立分区,而 ...
- SharePoint Server 2010安装图解
SharePoint Server 2010作为MOSS 2007的升级版本,自从2009年底发布Beta版本以来就备受关注,网络上已经出现了很多相关的文章,其中也不乏中文的信息. 最近SharePo ...
- Clone Graph——LeetCode
Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. OJ's ...