在上一篇文章中,小豆君介绍了QStandardItemModel的用法,并且了解了其储存单个数据项的QStandardItem类,而这些模型的层次结构,比如表格的行列,树结构的父子节点就需要一个类来进行定位,Qt中给它命名为QModelndex,字面意思上就是模型索引之意。
1 QModelndex
在软件接口设计中,要遵守的一个重要原则就是ISP(接口隔离原则),所以Qt为了确保数据的表示与访问方式保持隔离,引入了模型索引的概念。那么我们就可以将模型获得的每一块信息都用模型索引表示。
视图和委托使用这些索引来请求要显示的数据项。因此,只有模型才需要知道如何获取数据,并且模型管理的多种数据类型。
查看QAbstractListModel的接口,其所有接口都有一个共同的参数,就是QModelndex,所以有必要对这个类做一些详细介绍。
2 获取QModelndex方法
要获得对应于数据项的QModelndex,必须为QModelndex指定三个属性:行号、列号和父项的QModelndex,当我们知道了这三个属性,那么就可以找到数据项对应的QModelndex,从而对数据进行操控。
获取QModelIndex使用如下方法:
//参数:行号,列号,和其父节点的QModelIndex QStandardItemModel::index(int row, int column, const QModelIndex& parent = QModelIndex()) const //通过indexFromItem也可以获取索引,相对应的通过itemFormIndex可以获取item。 QModelIndex QStandardItemModel::indexFromItem(const QStandardItem *item) const //通过QStandardItem的index接口可以获取QModelIndex QModelIndex QStandardItem::index() const
2.1 根节点
在创建QStandardItemModel时会自动创建一个不可见的根节点,这个根节点用来作为所有可见顶层节点的父节点。
2.2 获取列表数据项索引
对于列表,只需要知道行号就可以获取索引。
QModelIndex idx = model->index(0, 0);//列号传入0即可
2.3 获取表格数据项索引
对于表格,其实是在行的基础上加上了列,如果将列理解成一维数据的展示,那表格可以理解为二维数据的展示,故在传入行号的同时,再传入列号就可以获取索引了。
QModelIndex idx = model->index(1, 2);//获取第2行第3列的数据,索引号都从0开始
2.4 获取树数据项索引
对于树,是在表格的基础上加上了层级结构,所以要再传入父节点的QModelIndex才可以获取索引。
QModelIndex indexA = model->index(0, 0, QModelIndex());//如果是顶层节点传入空的父节点索引即可 QModelIndex indexC = model->index(2, 1, QModelIndex()); QModelIndex indexB = model->index(1, 0, indexA);
3 item角色
模型中的item其实是由多个组件组成的,不同的组件可以显示不同的信息,比如显示文字,图标,复选框和提示信息。因此可用各种角色来匹配对应的组件,为不同的组件提供不同类型的数据。例如,Qt: DisplayRole用于访问可以在视图中显示为文本的字符串。这些标准角色由Qt::ItemDataRole定义。
4 总结
- 通过QModelIndex可以获取item在视图和委托中的位置信息,并将该信息提供给模型。并且QModelIndex是独立于任何底层数据结构的。
- item由它们的行和列号以及它们的父item的QModelIndex来引用。
- QModelIndex是根据其他组件(如视图和委托)的请求由模型构建的。因此,QModelIndex是动态的,例如删除一个item,其后的item索引就会被更新。所以一般不要储存索引,而是要实时获取。
- 模型中的根节点调用index接口返回的QModelIndex对象是无效的。
好了,关于今天的分享就到这里了,最后也希望大家多多支持小豆君的创作,关注公众号“小豆君Qt分享”,最新文章都会在公众号第一时间发布,也可加入C++\Qt交流群,一起学习。