关于 QAbstractItemModel 学习的一点分享

关于 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

posted on 2022-11-03 15:44  斗战胜佛美猴王  阅读(1094)  评论(0编辑  收藏  举报