关于 QAbstractItemModel 学习的一点分享
简介:
Qt的模型、视图框架对处理一些复杂数据结构的可视化非常有用。
Qt提供了三种常用的数据模型:QAbstractListModel (表单模型)、QAbstractTableModel (表格模型)、QAbstractItemModel (项目模型)。
其中第三种模型最灵活。前两种模型都是继承第三种模型的类的。
Qt的帮助文档里有提到:
If you need a model to use with an item view such as QML’s List View element or the C++ widgets QListView or QTableView, you should consider subclassing QAbstractListModel or QAbstractTableModel instead of this class.
可以看出,如果是listView 或者 tableView 那么就考虑前两种数据模型,但是如果是treeView,那就只好选择QAbstractItemModel (项目模型)了。
可以这样理解,QAbstractListModel 是QAbstractTableModel 的特殊化,QAbstractTableModel 是QAbstractItemModel 的特殊化。
接下来,我们着中来理解下QAbstractItemModel类。
关于QAbstractItemModel类的细节描述:
1、QAbstractItemModel 类提供了共模型视图框架中的其他组件访问的接口。
2、使用QAbstractItemModel 类,应当子类化。不能直接创建该类的对象。
3、AbstractItemModel 类 支持的 The underlying data model (底层的数据模型)是一个类似hierarchy of tables(有层级关系的表格),如果没有层级,那就只有rows(行) 和colums(列)。但在AbstractItemModel 类中,还有QModelIndex(索引),这样,每一个Item 就是一个独立的表格单元。如下图:
4、对于每一个数据单元(item of data)可以通过index() 索引,它的子项可以通过sibling()索引,它的父项可以通过parent()索引。
5、对于每一个数据单元都有一些data elements(数据元素)来界定( Qt::ItemDataRole)数据的角色。该数据元素可以通过data()放来来获取:
如:
QVariant str = item2->data(Qt::ToolTipRole);
qDebug()<<str;
下表列出了数据角色:
什么是数据角色?可以这样理解对于每个item呈现给用户的视角是多方面的,比如:ToolTipRole 角色中的数据是只有当鼠标移到视图中多对应的Item才会显示。
例如,下图中选中的Item中 有三个角色,分别是蓝色的图标、字符"B"、提示“”indexB“”。
6、在每一个item中,每个数据角色会对应一个数据,通过setData()方法来为指定的数据角色设定数据。setItemData()方法 则是为所有的数据角色设定相同的数据。
7、hasChildren()方法可以确认是否有子项。
8、对于一个层级的表格,都有关于行和列的操作
rowCount() 、columnCount()、 insertRows(), insertColumns(), removeRows(), and removeColumns().
9 、该模型该提供了一些信号来表示数据的变化:dataChanged()、headerDataChanged() 、layoutChanged()
子类化该模型
1、在只读模型和基本的可编辑模型中,至少需要重写index(), parent(), rowCount(), columnCount(), data()这些函数。
2、重写 hasChildren()函数来提供一些特殊的模型的行为。
3、如果模型是可编辑的,那么还需要重载setData() 和 flags().
4、重写headerData()和setHeaderData()对标题进行编辑。
5、在setData()和setHeaderData()函数中必须明确的加载 dataChanged() and headerDataChanged() 信号。
6、对于自定义模型,需要创建模型的索引,这里会用到createIndex()。
7、模型的重构会用到插入删除行列insertRows(), removeRows(), insertColumns(),and removeColumns(). 在这些操作中it is important to notify any connected views about changes to the model’s dimensions both before and after they occur:
例如:
bool TreeModel::insertColumns(int position, int columns, const QModelIndex &parent) { beginInsertColumns(parent, position, position + columns - 1); const bool success = rootItem->insertColumns(position, columns); endInsertColumns(); return success; }
8、重写fetchMore() and canFetchMore()使数据模型递增。
有关子类化的相关实现 可以参考Qt的示例代码:Simple Tree Model
在Qt的帮助文档中还有一篇 Model/View Programming 的介绍,该文档中Model Subclassing Reference 就有提到如何子类化
————————————————
版权声明:本文为CSDN博主「qq_21291397」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_21291397/article/details/106940977