Class  QAbstractItemModel:

使用QML的TreeView类来展示树状的结构,对应的是QT的Model/View模型。这个model是一个数据模型,要为TreeView提供一个模型,需要定义一个类,该类需要继承自calss QAbstractItemModel,不能直接使用该类。

另外,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.

定义的模型可以是有层次关系的(即有item含有孩子),模型被传递给Views和delegates. 如果模型没有层次关系,那么就指示一个简单的表格,表中的每个元素(item)都有唯一的index,index是 calss QModelIndex的对象,The QModelIndex class is used to locate data in a data model.

  • 模型中的每一个Item对应一个model index, 可以通过QAbstractItemModel::index函数来获取,但是该函数式纯虚函数,需要使用者自己实现,具体实现方法??
  • Each item has a number of data elements associated with it ,each with its own role, and these elements can be retrieved(检索,取出) by specifying a role (see Qt::ItemDataRole) to the model's data() function. Data for all available roles can be obtained at the same time using the itemData() function.   The roles are used by the view to indicate to the model which type of data it needs(View使用这些roles来告诉模型,自己需要模型的哪一中数据来显示在图形上). ---------- 没大明白,指的是模型中的每一个item都有很多属性吗,然后每一个属性对应着一个唯一的role,说属性的值就相当于说该属性的role的值?
  • Data for each role is set using a particular Qt::ItemDataRole. Data for individual roles are set individually with setData(), or they can be set for all roles with setItemData().---- Qt::ItemDataRole的作用是设置某个item的某个role对应的值。
  • Items can be queried with flags() (see Qt::ItemFlag) to see if they can be selected, dragged, or manipulated in other ways.---flags()为虚函数。
  • If an item has child objects, hasChildren() returns true for the corresponding index.----hasChildren()是虚函数。
  • The model has a rowCount() and a columnCount() for each level of the hierarchy. Rows and columns can be inserted and removed with insertRows(), insertColumns(), removeRows(), and removeColumns().-----rowCount() and a columnCount()是纯虚函数。
  • The model emits signals to indicate changes. For example, dataChanged() is emitted whenever items of data made available by the model are changed.-----我用过,但是没有明白最后一个入参是什么意思?
  • Changes to the headers supplied by the model cause headerDataChanged() to be emitted. If the structure of the underlying data changes, the model can emit layoutChanged() to indicate to any attached views that they should redisplay any items shown, taking the new structure into account.
  • The items available through the model can be searched for particular data using the match() function.
    To sort the model, you can use sort().

-------------

继承该类的注意事项:

1)继承该类时,以下几个函数必须自己实现:

index(), parent(), rowCount(), columnCount(), and data(). 这几个函数在所有的read-only模型中都会用到,而且是editable model的基础。

2)You can also reimplement hasChildren() to provide special behavior for models where the implementation of rowCount() is expensive. This makes it possible for models to restrict the amount of data requested by views, and can be used as a way to implement lazy population of model data.  -----??

3)为了使你的模型可以编辑,必须实现setData()函数,,还有flags()函数(保证ItemIsEditable 被返回),你也可以重新实现headerData()和setHeaderData()来控制模型的Header的展现方式。

4)dataChanged()和headerDataChanged()信号必须被显式地发出,当重新实现setData()和setHeaderData()函数时。

5)调用creatIndex()函数,来为模型的特定的一个item建立一个index,其他函数可以使用这个index来操作该item. 该函数接受3个参数,QModelIndex createIndex(int row, int column, void * ptr = 0),对于第三个参数的作用我不知道,但是QT5.5文档中有个例子“Simple Tree Model Example”

6)It is not necessary to support every role defined in Qt::ItemDataRole. Depending on the type of data contained within a model, it may only be useful to implement the data() function to return valid information for some of the more common roles.  Most models provide at least a textual representation of item data for the Qt::DisplayRole, and well-behaved models should also provide valid information for the Qt::ToolTipRole and Qt::WhatsThisRole. Supporting these roles enables models to be used with standard Qt views. However, for some models that handle highly-specialized data, it may be appropriate to provide data only for user-defined roles. ----- 没理解呢?

7)这一项我用过,哈哈,相当重要

只不过我没有重新实现现成的insertRows(), insertColumns()...,只是使用了beginInsertRows()这种信号。

Models that provide interfaces to resizable data structures can provide implementations of insertRows(), removeRows(), insertColumns(),and removeColumns(). When implementing these functions, it is important to notify any connected views about changes to the model's dimensions both before and after they occur:

An insertRows() implementation must call beginInsertRows() before inserting new rows into the data structure, and endInsertRows() immediately afterwards.

An insertColumns() implementation must call beginInsertColumns() before inserting new columns into the data structure, and endInsertColumns() immediately afterwards.

A removeRows() implementation must call beginRemoveRows() before the rows are removed from the data structure, and endRemoveRows() immediately afterwards.

A removeColumns() implementation must call beginRemoveColumns() before the columns are removed from the data structure, and endRemoveColumns() immediately afterwards.

The private signals that these functions emit give attached components the chance to take action before any data becomes unavailable. The encapsulation of the insert and remove operations with these begin and end functions also enables the model to manage persistent model indexes (一种类)correctly. If you want selections to be handled properly, you must ensure that you call these functions. If you insert or remove an item with children, you do not need to call these functions for the child items. In other words, the parent item will take care of its child items.

8)To create models that populate incrementally, you can reimplement fetchMore() and canFetchMore(). If the reimplementation of fetchMore() adds rows to the model, beginInsertRows() and endInsertRows() must be called.

-------------

QAbstractItemModel的有用的成员:

1) void QAbstractItemModel::beginResetModel()
Begins a model reset operation.
A reset operation resets the model to its current state in any attached views.
Note: Any views attached to this model will be reset as well.

When a model is reset it means that any previous data reported from the model is now invalid and has to be queried for again. This also means that the current item and any selected items will become invalid.
When a model radically changes its data it can sometimes be easier to just call this function rather than emit dataChanged() to inform other components when the underlying data source, or its structure, has changed.
You must call this function before resetting any internal data structures in your model or proxy model.This function emits the signal modelAboutToBeReset().This function was introduced in Qt 4.6.

----我用了这个函数后,界面上的TreeView会全部收缩起来,太气人了。

2) QAbstractItemModel::dataChanged-----  【signal】

void QAbstractItemModel::dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight, const QVector<int> & roles = QVector<int> ())

我用过:如果改变了模型中树结构上的某一个节点的属性,改完之后,可以调用emit dataChanged(modelindex, modelindex),然后界面上的树对应的该节点会相应的改变,modelindex指的是改节点的modelindex,最后一个入参我没有使用它.

This signal is emitted whenever the data in an existing item changes.
If the items are of the same parent, the affected ones are those between topLeft and bottomRight inclusive---说的是简单的网格结构吧. If the items do not have the same parent, the behavior is undefined.
When reimplementing the setData() function, this signal must be emitted explicitly.

The optional roles argument can be used to specify which data roles have actually been modified. An empty vector in the roles argument means that all roles should be considered modified. The order of elements in the roles argument does not have any relevance.

3) QAbstractItemModel::beginInsertRows(const QModelIndex & parent, int first, int last)----------protected 成员函数

When reimplementing insertRows() in a subclass, you must call this function before inserting data into the model's underlying data store.

The parent index corresponds to the parent into which the new rows are inserted; first and last are the row numbers that the new rows will have after they have been inserted.

我在处理TreeView时用过,如果要在一个父节点下插入新的孩子,则parent指的是该父节点对应的index,另外两个参数对应的是插入的位置。具体见qt文档,相当详细,其他的begin..都大体类似,注意begin..要与end..成对使用。

Note: This function emits the rowsAboutToBeInserted() signal which connected views (or proxies) must handle before the data is inserted.

4)beginMoveRows, beginRemoveColumns....... 都是很有用的信号。

5)columnCount(const QModelIndex & parent = QModelIndex()) const,纯虚函数

Returns the number of columns for the children of the given parent.

Related: rowCount();

6) QModelIndex QAbstractItemModel::createIndex(...)---------------????没明白

Creates a model index for the given row and column with the internal pointer ptr.

7) QVariant QAbstractItemModel::data(const QModelIndex & index, int role = Qt::DisplayRole) const---------????没明白
    Returns the data stored under the given role for the item referred to by the index.
    Note: If you do not have a value to return, return an invalid QVariant instead of returning 0.

8)其他不太理解的函数:

buddy, canDropMimeData, canFetchMore, changePersistentIndex,dropMimeData,match,扥等。看来该类给用户提供了很多虚函数,可以让使用者去重新实现,很好地对类的功能进行了细分和规划。

-------------------------------------------------------------------------

QT中与QAbstractItemModel类相似的类还有  QAbstractListModel ,但是 QAbstractListModel 类只能提供一维的模型,适用于为QListView提供模型:

“The QAbstractListModel class provides an abstract model that can be subclassed to create one-dimensional listmodels.
QAbstractListModel provides a standard interface for models that represent their data as a simple non-hierarchical sequence of items. It is not used directly, but must be subclassed.

Since the model provides a more specialized interface than QAbstractItemModel, it is not suitable for use with tree views; you will need to subclass QAbstractItemModel if you want to provide a model for that purpose. If you need to use a number of list models to manage data, it may be more appropriate to subclass QAbstractTableModel instead.

----------------------------------------------------------------------------

QT文档自带的例子:

1)在qt creator Help中搜索:Simple Tree Model Example---应该会很好吧。

2)

相关资源:

1)博客例子: https://blog.csdn.net/shado_walker/article/details/56495059


QT qml TreeView展示数据结构于界面的更多相关文章

  1. Qt qml treeview 树控件

    qml并没有提供树控件,只能自己写了.model仍然用ListModel对象,弄成层级的就行.delegate必须用loader动态的增加子控件,如此而已. [先看效果] [下载] http://do ...

  2. qt qml Treeview使用记录--设置每个Item的图片logo,高度

    这篇帮助很大: https://blog.csdn.net/qq_32116695/article/details/81298585, 代码如下: TreeView { id: viewTree an ...

  3. QML与C++交互:登陆界面设计

    QML与C++交互:登陆界面设计 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 环境: 主机:WIN7 开发环境:Qt5.2.1 说明: QML设计前 ...

  4. qt qml qchart 图表组件

    qt qml qchart 图表组件 * Author: Julien Wintz * Created: Thu Feb 13 23:41:59 2014 (+0100) 这玩意是从chart.js迁 ...

  5. Qt QML referenceexamples attached Demo hacking

    /********************************************************************************************* * Qt ...

  6. Qt qml 单例模式

    Qt qml 单例模式,没什么好说的,看代码吧.单例模式很适合做全局的配置文件. [示例下载] http://download.csdn.net/detail/surfsky/8539313 [以下是 ...

  7. Qt qml listview 列表视图控件(下拉刷新、上拉分页、滚动轴)

    Qt qml listview下拉刷新和上拉分页主要根据contentY来判断.但要加上顶部下拉指示器.滚动条,并封装成可简单调用的组件,着实花了我不少精力:) [先看效果]    [功能] 下拉刷新 ...

  8. qt qml中PropertyAnimation的几种使用方法

    qml文章 qt qml中PropertyAnimation的几种使用方法 动画应用场景有以下几种: 首先如果一个Rectangle.动画是要改变它的x和y值 1,Rectangle一旦被创建,就要移 ...

  9. Qt之实现360安全卫士主界面代码开源

    匆匆一年又过去了,总结去年一年的节奏就是忙爆了:生活忙.工作忙,值得庆幸的是没有瞎忙:今天打开博客园查看我的博客,才发现几乎差不多一年时间没写博客了:博客文章就是记忆,就是曾经努力过的见证,感谢博客园 ...

随机推荐

  1. Android精通教程-Android入门简介

    前言 大家好,我是 Vic,今天给大家带来Android精通教程-Android入门简介的概述,希望你们喜欢 每日一句 If life were predictable it would cease ...

  2. FLUENT质量加权平均和面积加权平均的区别【转载】

    转载自:http://blog.sina.com.cn/s/blog_7ef78d170101bhfn.html 网上关于fluent中质量加强平均(Mass-Weighted Average)和面积 ...

  3. go中的方法以及自定义类型代码示例

    package main import "fmt" type user struct { name string age int sex string } type admin s ...

  4. PostgreSQL学习笔记(九) 用户、角色、权限管理

    PostgreSQL是一个多用户数据库,可以为不同用户指定允许的权限. 角色PostgreSQL使用角色的概念管理数据库访问权限. 根据角色自身的设置不同,一个角色可以看做是一个数据库用户,或者一组数 ...

  5. STM32 软件按键消抖

    引言 通常按键所用的开关都是机械弹性开关,当机械触点断开.闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上就稳定的接通,在断开时也不会一下子彻底断开,而是在闭合和断开的瞬间伴随了一连串的抖 ...

  6. ubuntu16.04 18.04 Qt5.11安装Gstreamer

    最近因为要做跨平台的视频传输,需要用到linux的解码器,真的是搞死我了 大概讲一下我现在的平台是ubuntu16.04 Qt5.11 ,我现在需要在我的程序中使用视频这一块,无奈linux中,Qt支 ...

  7. JVM 自定义类加载器

    一.创建自定义类加载器 package com.example.jvm.classloader; import java.io.ByteArrayOutputStream; import java.i ...

  8. vue入门|ElementUI使用指南

    vue入门|ElementUI使用指南 1.开发前务必熟悉的文档: vue.js2.0中文,项目所使用的js框架 vue-router,vue.js配套路由 vuex 状态管理 Element UI框 ...

  9. Linux系列 | Ubuntu 各版本号和名称对照【转】

    转载处:https://blog.csdn.net/songfulu/article/details/85310273   版本 开发代号 中译 发布日期 支持结束时间 内核版本 桌面版 服务器版 4 ...

  10. DNS 预读取功能 链接预取

    https://developer.mozilla.org/zh-CN/docs/Controlling_DNS_prefetching DNS 请求需要的带宽非常小,但是延迟却有点高,这一点在手机网 ...