关于QStandardItemModel

类QabstractItemModel,QabstractListModel,QAbstractTableModel不保存数据,用户需要从这些类派生出子类,并在子类中定义某种数据结构来保存数据。与此不同,类QStandardItemModel负责保存数据,每个数据项被表示为类QStandardItem的对象。我们首先阐述如何使用类QStandardItem保存一个数据项,再阐述如何使用类QStandardItemModel将这些数据项组织起来,形成列表、表格或者树,以供其他视图类显示。

如前文所述,一个数据项由若干个『角色,数据子项』对组成。类QStandardItem负责保存、访问这些数据。该类的内部定义了一个类型为QVector的容器,每个容器元素本质上存放一个『角色,数据子项』对。

由于各个角色对应的数据子项可能具有不同的类型,Qt使用QVariant来存放每个数据子项。当用户希望将一些数据存放在一个QStandardItem对象中时,可以调用其成员函数:
void setData ( const QVariant & value, int role)
将『role, value』对存入。当用户希望读取该对象中的数据时,可以调用另外一个成员函数:

QVariant data ( int role = ) const

读取角色role对应的数据子项。

以上两个函数是QStandardItem的核心。有了这两个函数,我们就可以访问该类所表示数据项的任何一个『角色,数据子项』对。然而,对于一些常用角色,该类提供了更加简洁、容易记忆的成员函数。例如,当一个数据项被显示在视图中时,它往往包含一些文字、一个图标,还可能包含一个复选框。角色Qt::BackgroundRole控制显示背景,Qt::FontRole控制文字字体,Qt::ForegroundRole控制文字颜色,Qt::CheckStateRole控制复选框的状态。该类提供的一组成员函数可以方便地访问这些常用角色对应的数据子项。成员函数setBackground()、background()分别设置/返回背景刷子。函数setFont()、font()分别设置/返回文字字体。函数setForeground()、foreground()分别设置/返回字体颜色。函数setCheckState()、checkState()分别设置/返回复选框状态。

类QStandardItemModel将类QStandardItem表示的数据项组织起来,形成列表、表格、树甚至更复杂的数据结构。该类提供了一组成员函数,向这些数据结构添加新的数据项,更改已经存在的数据项,或者删除已有的数据项。另一方面,作为一个模型类,它实现了QAbstractItemModel定义的接口函数,以使其他视图类能够访问模型中的数据项。

如果数据集被表示为一个列表,我们可以调用类QStandardItemModel的成员函数appendRow()向列表中添加一个数据项,使用item()读取一个数据项,如代码段13 10所示。行①获取模型最顶层的根节点,行②创建一个QStandardItem对象,表示一个数据项,行③将该数据项作为根节点的子节点添加到列表中。行②的构造函数在内部调用该类的setData()函数,将行②的QString对象作为Qt::DisplayRole对应的数据子项存入新构造的对象。由于数据集本身是一个列表,所以我们使用QListView显示该数据集,读者可以运行该例子查看显示结果。

代码段13 10,使用QStandardItemModel处理列表,取自z:\examples\mvc\QStandardItemModel_demo\main.cpp
QStandardItemModel listModel;
QStandardItem *rootItem = listModel.invisibleRootItem();          ①
for (int row = 0; row < 4; ++row) {
 QStandardItem *item = new QStandardItem(QString("%0").arg(row) );②
 rootItem->appendRow( item );  ③

QListView listView;
listView.setModel ( & listModel );

如果数据集被表示为一个表格,可以调用类QStandardItemModel的成员函数setItem()设定表格中的某个数据项,如代码段13 11所示。由于这个代码段中的数据集是一个表格,所以使用QTableView显示该数据集。

代码段13 11,使用QStandardItemModel处理表格,取自z:\examples\mvc\QStandardItemModel_demo\main.cpp
QStandardItemModel tableModel(4, 4);
 for (int row = 0; row < 4; ++row) {
   for (int column = 0; column < 4; ++column) {
    QStandardItem *item = new QStandardItem(
     QString("%0,%1").arg(row).arg(column));
    tableModel.setItem(row, column, item);
   }
 } 
 QTableView tableView;
 tableView.setModel( & tableModel );

如果数据集被表示为一个树,可以调用类QStandardItemModel的成员函数appendRow()向某个树节点添加子节点。通过多次调用该函数,可以构建一棵复杂的树。代码段13 12构建一棵简单的树:最顶层的根节点有一个文字内容为“0”的子节点,该子节点有一个文字内容为“1”的子节点。依此类推,“1”子节点有一个“2”子节点,“2”子节点有一个“3”子节点,形成一棵深度为4的树。这棵树的每个节点都没有兄弟节点(具有相同父节点的多个节点被相互称为兄弟节点),感兴趣的读者可以修改这段代码,以使其中某些节点具有兄弟节点。由于数据集是一棵树,我们使用QTreeView显示它。

代码段13 12,使用QStandardItemModel处理树,取自z:\examples\mvc\QStandardItemModel_demo\main.cpp
QStandardItemModel treeModel;
QStandardItem *parentItem = treeModel.invisibleRootItem();
for (int i = 0; i < 4; ++i) {
 QStandardItem *item = new QStandardItem(QString("%0").arg(i));
 parentItem->appendRow(item);
 parentItem = item;
}
QTreeView treeView;
treeView.setModel( & treeModel );

类QStandardItemModel之所以能够表示列表、表格、树甚至更复杂的数据结构,得益于类QStandardItem在其内部定义了一个类型为QVector<QStandardItem*>的容器,可以将每个容器元素所指的QStandardItem对象设定为子对象。表现在如图13 13所示的类图上,类QStandardItem和自身具有“children”关系。一个类和自身发生关联,在UML中被称为自关联(self association)。类QStandardItemModel定义了一个名为root的数据成员,逻辑上是一个指向QStandardItem对象的指针。这个对象可以设定多个QStandardItem的对象作为自己的子对象,而其中每个子对象又可以包含其他的子对象。依此类推,这棵树可以具有任意深度,每个父对象可以包含任意多个子对象。

很自然地,QStandardItemModel可以使用QStandardItem表示具有树状数据结构的数据集,如图13 14所示。图中的每个小方框表示类QStandardItem的一个对象。如果小方框的边线为虚,相应的QStandardItem对象并不表示数据集中的任何数据,仅被用来表示某种数据结构。如果小方框的边线为实,相应的QStandardItem对象就表示数据集中的一个数据项。在右侧的图中,QStandardItemModel的数据成员root所指的对象表示一个不可见的根,而数据集的根(图中结点G)被表示为这个不可见根的一个子节点。

列表被看作一个特殊的树:不可见根具有若干个子节点,每个子节点表示列表中的一个数据项,不再包含任何子节点,如该图左侧所示。而表格的表示方式反而麻烦一些。不可见根含有若干子节点(图中A,B,C),这些子节点并不表示数据集中的任何数据项。第i个子节点会包含若干子节点(比如图中D,E,F),这些子节点才表示表格第i行的数据项。

使用QStandardItemModel表示数据集具有以下优点:该类使用QStandardItem存放数据项,用户不必定义任何数据结构来存放数据项;QStandardItem使用自关联关系,能够表达列表、表格、树甚至更复杂的数据结构,能够涵盖各种各样的数据集;QStandardItem本身存放着多个『角色,数据子项』,视图类、委托类或者其他用户定义的类能够方便地依据角色访问各个数据子项。

然而,这种表示方法也有局限性:当数据集中的数据项很多时,施加在数据集上的某些操作的执行效率会很低。比如,设数据集是一个1万行、20列的表格,其中第10列存放的是浮点数。如果我们想计算这一列的平均值,按照图13 14,这需要遍历所有行,取得第10列的QStandardItem对象,再依据角色“Qt::DisplayRole”取得对应的数据子项。由于这个数据子项的类型为QString,还需要将其转换为浮点数,最后求所有浮点数的平均值。这些操作会耗费较长的时间。

因此,对于数据量不是很大、对性能要求不是很高的场合,我们可以使用类QStandardItemModel来表示一个数据集。否则,用户应该从QAbstractItemModel、QAbstractListModel或者QAbstractTableModel派生新类,自行管理数据集的存放与访问

原文地址:https://www.cnblogs.com/senior-engineer/p/8514004.html

时间: 2024-10-19 04:00:55

关于QStandardItemModel的相关文章

QStandardItemModel简单好用,QTableView带进度条

类QabstractItemModel,QabstractListModel,QAbstractTableModel不保存数据,用户需要从这些类派生出子类,并在子类中定义某种数据结构来保存数据.与此不同,类QStandardItemModel负责保存数据,每个数据项被表示为类QStandardItem的对象.我们首先阐述如何使用类QStandardItem保存一个数据项,再阐述如何使用类QStandardItemModel将这些数据项组织起来,形成列表.表格或者树,以供其他视图类显示. 理论参考

QStandardItemModel角色控制及QTreeView加入不同的右键菜单

1.概述 QTreeView最长用的一个功能就是作为导航栏,像vs里的项目结构树,word的文档结构图,资源管理器的文档结构,等等都是利用树形结构组织的,在前面已经讲述了Qt中使用标准化项目模型QStandardItemModel对树形控件节点的操作.但有时候,光有节点显示还是不够的,还须要和用户进行交互,如右键点击不同条目会出现不同菜单,这时就须要知道各个节点相应的功能. 在MFC里,树形控件CTreeCtrl是通过SetItemData函数来对节点设置一个指针的值,这个值能够是个指针或者DW

QStandardItemModel角色控制及QTreeView添加不同的右键菜单

1.概述 QTreeView最长用的一个功能就是作为导航栏,像vs里的项目结构树,word的文档结构图,资源管理器的文档结构,等等都是利用树形结构组织的,在前面已经讲述了Qt中使用标准化项目模型QStandardItemModel对树形控件节点的操作.但有时候,光有节点显示还是不够的,还需要和用户进行交互,如右键点击不同条目会出现不同菜单,这时就需要知道各个节点对应的功能. 在MFC里,树形控件CTreeCtrl是通过SetItemData函数来对节点设置一个指针的值,这个值可以是个指针或者DW

QTableView与QStandardItemModel基本使用方法

对表格型数据,Qt有现成的模型/视图类,QStandardItemModel类和QTableView类. 模型类提供数据,视图类则负责展示数据.所以数据及数据的相关信息(如文本大小.颜色.数据类型等)由模型类(QStandardItemModel)管理,数据的显示(如表格是否可以编辑.选择方式.行列的大小策略等)由视图类(QTableView)管理. 所以Qt表格模型和视图的使用步骤大致如下: 1. 创建模型对象 1 QStandardItemModel *import_model = new

QStandardItemModel中设置项目的背景颜色

如何根据内容显示不同的背景颜色? 参照ECMWF的Metview源码实现. Qt的Model中不同类型的数据用role区分,Qt的宏ItemDataRole提供了一些角色: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 enum ItemDataRole { DisplayRole = 0, DecorationRole = 1, EditRole = 2, ToolT

QDemo之QStandardItemModel

自定义树形模型 //treeView.h //不要忘了包含这2个头文件:QStandardItem/QStandardItemModel public:QStandardItemModel *getTreeModel(); //treeView.cpp //获取树形模型 QStandardItemModel *TreeView::getTreeModel() { QStandardItemModel *model = new QStandardItemModel(this); QStandard

QComboBox实现复选功能(三种方法:嵌套QListWidget, 设置QStandardItemModel, 设置Delegate)

今天介绍一下一个小东西 — 如何让QComboBox实现复选功能? 需求: 下拉列表有复选功能 不可编辑 显示所有选中项 关于QComboBox的复选功能有几种方案: QStandardItemModel + QStandardItem QListWidget + QListWidgetItem Model/View + QItemDelegate 当然,还有其它更好的方式,这里就不再过多介绍了,下面介绍一种比较简单的: QListWidget + QListWidgetItem + QChec

QStandardItemModel

最近在阅读Qt 5.9 C++开发指南,为了加深对书本上内容的理解,参照书上的讲解尝试写了一些demo,用于以后工作中查阅,如果涉及侵权请告知,实例程序samp5_3 mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QTableView> #include <QPlainTextEdit> #include <QLabel> #in

第59课 自定义模型类(中)

1. 系统架构图(续上节的实例分析) 2. 类的设计与实现 (1)DataSource类的设计与实例 ①设置数据源并读取数据 ②对数据进行解析后生成数据对象 (2)ScoreInfo类的设计与实现 ①封装数据源中的一组完整数据(即一条记录信息) ②提供返回具体数据值的接口函数 (3)ScoreInfoModel类的设计与实现 ①使用标准模型类QStandardItemModel作为成员(这里采用组合方式,而不采用继承) ②以ScoreInfo类对象为最小单位进行数据组织 3. 数据交互流程图 [