文档章节

最近在学Qt模型,转载一篇觉得有用的 Qt模型类

吥楛糖
 吥楛糖
发布于 2012/07/28 15:11
字数 2576
阅读 268
收藏 2

转至:http://www.cnblogs.com/weiweiqiao99/archive/2011/04/12/2013957.html (貌似他也是转的,已经找不到根源了)

在模型/视图架构中,模型提供一个标准的接口供视图和委托(view/delegate)用来访问数据。在Qt中,这个标准的接口是由类QAbstractItemModel定义的。无论底层数据结构中的数据是如何存储的,类QAbstractItemModel的所有子类都将数据表示为一个包含由数据项组成的表格的层次型结构。视图按照这个约定来访问模型中的数据项,但是它们将信息展示给用户的时候不需要这样来做。

模型也使用信号和信号槽机制来向关联的视图通知关于数据的变化。

模型索引

为了确保数据的表示与数据被访问的方式是分开独立的,引入了模型索引(modelindex)的概念。每一个可以通过模型来获取的信息都被一个模型索引来表示。视图和委托使用这些模型索引来获取要显示的数据项(视图/委托操作的不是数据项,实际上操作的是保存了数据项内容的模型索引)。

结果是,只有模型需要知道如何获取数据,并且被该模型管理的数据的种类可以进行很广泛的定义。模型索引包含一个指向创建它们(模型索引)的模型的指针,这一点避免了在使用不止一个模型来工作时所产生的混乱。

QAbstractItemModel *model = index.model();

模型索引提供对信息片段的临时引用,可以被用来通过模型获取或者修改数据。由于模型可能会重新组织它们内部的数据结构,因此模型索引可能会失效,所 以不应当被保存。 如果你需要对一个信息片段的长期的引用,那么你必须创建一个持久模型索引。这样就提供了一个指向模型所维护的最新数据的引用。临时模型索引由 QModelIndex类提供,持久模型索引由QPersistentModelIndex类提供。

要获得对应于某一个数据项的模型索引,需要告诉模型3个属性:1个行号,1个列号,和父数据项的模型索引。接下来的小节描述及详细解释这些属性。

行与列

在最基本的形式下,一个模型可以被当作一个简单的表格来访问,在这个表格中数据项是通过行号和列号来定位的。这并不是说底层的数据片段存储在一个 矩阵结构中;行号和列号的使用只是一个用来让部件之间进行通信的约定。我们可以通过向模型提供任意指定的项目的行号和列号来获取它的信息,我们会获得一个 表示该数据项的模型索引:

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()作为它们的父对象项目来引用的。这一点是在下一节描述的。


数据项的父对象

模型针对数据项提供的类似表格的接口完美适用于在表格或者列表视图中使用数据;行号和列号系统准确地与视图显示项目的方式对应。然而,像树视图这样的结构要求模型针对它管理的项目展现出一个更灵活的接口。结果是,每个数据项也可以作为另一个数据项组成的表格的父对象,就像树视图中的一个顶层数据项可以包含另一个由数据项组成的列表一样。

当我请求一个模型数据项的模型索引时,我也必须提供一些关于它的父对象的信息。在模型之外,指向一个项目的唯一的方法就是使用一个模型索引,所以一个父对象模型索引也必须被给出:

QModelIndex index = model->index(row, column, parent);

父对象,行和列

这个图显示的是一个树模型的表示方式,其中,每个数据项是使用一个父对象、一个行号和一个列号来索引的。

项目“A”和“C”在模型中是被以顶级的兄弟节点的方式来表示的:

QModelIndex indexA = model->index(0, 0, QModelIndex());

QModelIndex indexC = model->index(2, 1, QModelIndex());


项目“A”有一些子对象。项目“B”的模型索引是以下面的代码来获取的:

QModelIndex indexB = model->index(1, 0, indexA);


数据项角色

一个模型中的数据项可以为其它部件扮演各种各样的角色,以便为不同的情况来使用不同种类的数据。例如,Qt::DisplayRole用来在一个视图中获取一个可以被当成文本显示的字符串。一般地,数据项都包含了用于很多不同角色的数据,而标准的角色是被Qt::ItemDataRole定义的。

我们可以通过向模型传递对应于一个数据项的模型索引来获取它的数据,并且通过指定一个角色来获取我们想要的类型的数据:

QVariant value = model->data(index, role);

数据项角色

角色指示模型哪种类型的数据是我们想要的。视图可以以不同的方式来显示不同的角色,所以为每个角色提供合适的信息是很重要的。

创建新的模型一节更加具体地讲述了关于角色的一些特殊用法。

数据项数据的最常用的用法是被Qt::ItemDataRole中定义的标准角色描述的。通过为每个角色提供适当的数据项数据,模型可以为视图和委托提供关于数据项该如何显示给用户的提示。不同的视图可以自主选择是按照要求来忽略这个提示还是遵从这个提示。也可以定义附加的角色,以用于实现应用程序特定的目的。

概念的总结

  • •.模型索引以一种不依赖于任何底层数据结构的方式来向视图和委托提供关于模型所提供的数据项的位置的信息。
  • •.数据项是通过行号、列号和它们的父对象的模型索引来引用的。
  • •.模型索引是模型在其它组件,例如视图和委托的请求下构造的。
  • •.如果在使用index()来请求模型索引时,一个有效的模型索引被当作父项目的索引来指定,那么返回的索引将会指向模型中在该父数据项下方的一个子数据项。获取的模型索引指向那个父数据项的一个子数据项。
  • •.如果在使用index()来请求索引时,一个无效的模型索引被当作父数据项的模型索引来指定,那么返回的索引将会指向模型中的一个顶层数据项。
  • •.角色区分与一个数据项结合的不同类型的数据。

使用模型索引

为了演示如何使用模型索引来从模型中取得数据,我们设置一个没有视图的QFileSystemModel,并且在一个部件中显示文件和目录的名字。尽管这没有展示出一个使用模型的标准方式,但是它展示了使用模型索引时在模型中使用的一些约定。

我们以下面的方式来构造一个文件系统模型:

QFileSystemModel *model = new QFileSystemModel;
QModelIndex parentIndex = model->index(QDir::currentPath());
int numRows = model->rowCount(parentIndex);


在这种情况下,我们建立一个默认的QFileSystemModel,使用该模型提供的特定的index()实现来获取一个父对象索引,再使用函数rowCount()来统计该模型中的行数。

简便起见,我们只关心该模型中第一列的项目。我们按顺序检查每一行,获取每一行中第一个项目的模型索引,再读取模型中为该项目储存的数据。

for (int row = 0; row < numRows; ++row) {
QModelIndex index = model->index(row, 0, parentIndex);}

为了获得一个模型索引,我们指定行号、列号(为第一列指定为0),以及针对所有我们想要获取的项目的父项目的合适的模型索引。保存在每个项目中的文本是使用模型的data()函数来获取的。我们指定模型索引和DisplayRole以便以字符串的形式来获取该项目的数据。

QString text = model->data(index, Qt::DisplayRole).toString();
// Display the text in a widget.

上面的例子展示了从模型中获取数据时所用的基本原则:

  • •.一个模型的维度可以使用rowCount()和columnCount()来获取。这些函数通常要求指定一个父模型索引。
  • •.模型索引用来访问模型中的项目。要指定一个项目,需要行号、列号和父模型索引。
  • •.要访问模型中的顶级项目,需要使用QModelIndex()来指定一个空的模型索引作为父索引。
  • •.项目都包含针对不同角色的数据。为了获取一个指定角色的数据,必须同时向模型提供模型索引和角色。

 

本文转载自:http://www.cnblogs.com/weiweiqiao99/archive/2011/04/12/2013957.html

吥楛糖

吥楛糖

粉丝 27
博文 4
码字总数 0
作品 0
深圳
程序员
私信 提问
加载中

评论(1)

太空堡垒185
太空堡垒185
我应该是转自豆子的博客。devbean
Qt自定义界面类并提升(提升的窗口部件),把OpenGL绘制的图形显示在QT的ui界面上

编译环境:Qt Creator 5.4.0_mingw 最近利用QT做一个上位机界面,想用OpenGL将STL文件还原成三维模型,并将模型显示出来,那么问题来了,最简单的显示就直接创建一个窗口显示模型,根本就 没...

u014546553
2017/07/04
0
0
【Qt笔记】model/view 架构

有时,我们的系统需要显示大量数据,比如从数据库中读取数据,以自己的方式显示在自己的应用程序的界面中。早期的 Qt 要实现这个功能,需要定义一个组件,在这个组件中保存一个数据对象,比如...

大道无名
2016/08/01
71
0
QT学习探索之路

近期由于工作需要在学习QT做界面开发,再次将我最近一个月的学习心得记录,同时欢迎各位大牛给我提出学习建议。 1:我的学习方法: 第一阶段: 主要是参考 C++ GUI Qt4 编程这本书 主要学习Q...

wb999999abc
2017/05/20
0
0
QT model-view架构

我们的系统有很多数据显示的需求,比如从数据库中把数据取出,然后以自己的方式显示在我们自己的应用程序的界面中。进行这一操作的典型方式是使用Qt的Item View类。 在早期的Qt版本中,要实现...

晨曦之光
2012/04/13
961
0
隐马尔可夫模型(六)——隐马尔可夫模型的评估问题(前向后向相结合算法)

重新回顾: 前向变量αt(i):在时刻t,在已知模型μ=(A,B,π)的条件下,状态处于si,输出序列为O102...Ot,前向变量为αt(i) 后向变量βt(i):在时刻t,在已知模型μ=(A,B,π)和状态处于si的条...

技术mix呢
2017/12/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

作为一个(IT)程序员!聊天没有话题?试试这十二种技巧

首先呢?我是一名程序员,经常性和同事没话题。 因为每天都会有自己的任务要做,程序员对于其他行业来说;是相对来说比较忙的。你会经常看到程序员在发呆、调试密密麻麻代码、红色报错发呆;...

小英子wep
今天
12
0
【SpringBoot】产生背景及简介

一、SpringBoot介绍 Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程,该框架使用了特定的方式来进行配置,从而使开发人员不再需要...

zw965
今天
4
0
简述并发编程分为三个核心问题:分工、同步、互斥。

总的来说,并发编程可以总结为三个核心问题:分工、同步、互斥。 所谓分工指的是如何高效地拆解任务并分配给线程,而同步指的是线程之间如何协作,互斥则是保证同一时刻只允许一个线程访问共...

dust8080
今天
6
0
OSChina 周四乱弹 —— 当你简历注水但还是找到了工作

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @花间小酌 :#今日歌曲推荐# 分享成龙的单曲《男儿当自强》。 《男儿当自强》- 成龙 手机党少年们想听歌,请使劲儿戳(这里) @hxg2016 :刚在...

小小编辑
今天
3.3K
22
靠写代码赚钱的一些门路

作者 @mezod 译者 @josephchang10 如今,通过自己的代码去赚钱变得越来越简单,不过对很多人来说依然还是很难,因为他们不知道有哪些门路。 今天给大家分享一个精彩的 GitHub 库,这个库整理...

高级农民工
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部