QAbstractItemModel使用样例与解析
来源:互联网 发布:sai绘图软件中文版 编辑:程序博客网 时间:2024/06/05 03:40
(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)
参考:qt源码
qstandarditemmodel_p.h
qstandarditemmodel.h
qstandarditemmodel.cpp
qabstractitemmodel.h
qabstractitemmodel.cpp
QAbstractItemModel是一个接口类,使用时需要从它继承下来,实现相关的函数后使用。
不同于QStandardItemModel,使用QAbstractItemModel的话,需要自己构造树形结构数据,并在虚函数中返回对应的值。
当然,简单使用的话,也可以快速构造出没有父节点的简单表格结构。
形如根节点下列了几排几列子节点的表格情形。
需要继承的类有:
class HistoryModel : public QAbstractItemModel{public: explicit HistoryModel(QObject *parent = 0); // 构造父节点下子节点的索引 virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; // 通过子节点索引获取父节点索引 virtual QModelIndex parent(const QModelIndex &child) const override; // 获取父节点下子节点的行数 virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; // 获取父节点下子节点列数 virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override; // 获取节点数据:包括DisplayRole|TextAlignmentRole等 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;};
实现几排几列表格情形的例子:
HistoryModel::HistoryModel(QObject *parent /*= 0*/) : QAbstractItemModel(parent){}QModelIndex HistoryModel::index(int row, int column, const QModelIndex &parent /*= QModelIndex()*/) const{ // 创建普通索引 return createIndex(row, column);}QModelIndex HistoryModel::parent(const QModelIndex &child) const{ // 父节点均为跟节点 return QModelIndex();}int HistoryModel::rowCount(const QModelIndex &parent /*= QModelIndex()*/) const{ // 根节点下有5行,其它行下没有 if (parent.row() == -1) { return 5; } return 0;}int HistoryModel::columnCount(const QModelIndex &parent /*= QModelIndex()*/) const{ // 每行有量列 return 2;}QVariant HistoryModel::data(const QModelIndex &index, int role /*= Qt::DisplayRole*/) const{ // 节点内容:左对齐,显示行列号 if (role == Qt::TextAlignmentRole) return int(Qt::AlignLeft | Qt::AlignVCenter); else if (role == Qt::DisplayRole) return QString("row=%1,col=%2").arg(index.row()).arg(index.column()); else return QVariant();}
进一步使用,添加树形结构,自己构造树形结构数据:
struct NodeInfo{ QModelIndex parent; // 父节点index QString sData; // 自身数据 QVector<NodeInfo*> childNodes; // 子节点 NodeInfo(QModelIndex parentIdx, QString s):parent(parentIdx), sData(s){}};
生成如下的这种界面:两个level=1节点,每个节点下有一些数据
可以这样来做:
每个节点存储一个NodeInfo信息,这样
1. 每个节点可以查询子节点数量
2. 每个节点可以查询到自身数据
3. 可以根据NodeInfo信息(row/col/this)获取到QModeIndex
4. 数据构造时,形成NodeInfo的树形层次
5. QAbstractItemModel的接口中,index函数中绑定NodeInfo
6. QAbstractItemModel的其它接口中,查询NodeInfo并使用
HistoryModel::HistoryModel(QObject *parent /*= 0*/) : QAbstractItemModel(parent){ // 创建root节点 m_pRootNode = new NodeInfo(nullptr, "rootNode", -1, -1); m_receiveInfo = new NodeInfo(m_pRootNode, "ReceiveMessage", 0, 0); m_replyInfo = new NodeInfo(m_pRootNode, "ReplyMessage", 1, 0); m_pRootNode->childNodes.append(m_receiveInfo); m_pRootNode->childNodes.append(m_replyInfo);}QModelIndex HistoryModel::index(int row, int column, const QModelIndex &parent /*= QModelIndex()*/) const{ if (parent.row() == -1 && parent.column() == -1) { // 首层节点绑定关系 if (row < m_pRootNode->childNodes.count()) return createIndex(row, column, m_pRootNode->childNodes[row]); } else { // 其它层节点绑定关系 if (parent.internalPointer() != nullptr) { NodeInfo* pNode = reinterpret_cast<NodeInfo*>(parent.internalPointer()); if (pNode->childNodes.size() > row) { return createIndex(row, column, pNode->childNodes[row]); } } } return QModelIndex();}QModelIndex HistoryModel::parent(const QModelIndex &child) const{ if (child.internalPointer() != nullptr) { NodeInfo* pNode = reinterpret_cast<NodeInfo*>(child.internalPointer()); NodeInfo* pParent = pNode->parent; if (pParent != nullptr) { // 根据父节点信息:row/col/node*获取Index return createIndex(pParent->nRow, pParent->nCol, pParent);; } } return QModelIndex();}int HistoryModel::rowCount(const QModelIndex &parent) const{ if (parent.internalPointer() == nullptr) { // 根节点下的数据行数 return m_pRootNode->childNodes.count(); } else { // 节点下的数据行数 NodeInfo* pNode = reinterpret_cast<NodeInfo*>(parent.internalPointer()); return pNode->childNodes.size(); }}int HistoryModel::columnCount(const QModelIndex &parent /*= QModelIndex()*/) const{ // 每行有量列 return 1;}QVariant HistoryModel::data(const QModelIndex &index, int role /*= Qt::DisplayRole*/) const{ // 节点内容:左对齐,显示行列号 if (role == Qt::TextAlignmentRole) { return int(Qt::AlignLeft | Qt::AlignVCenter); } else if (role == Qt::DisplayRole) { if (index.internalPointer() == 0) { return QString("row=%1,col=%2").arg(index.row()).arg(index.column()); } else { NodeInfo* pNode = reinterpret_cast<NodeInfo*>(index.internalPointer()); return pNode->sData; } } else { return QVariant(); }}
(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)
阅读全文
1 0
- QAbstractItemModel使用样例与解析
- QT中QTreeView与QAbstractItemModel使用中QTreeViwe的美化
- 简单描述QAbstractItemModel::dataChanged() 与 QAbstractItemModel::data() 的关系
- 重写QAbstractItemModel
- QAbstractItemModel,QAbstractTableModel
- QAbstractItemModel 数据更新
- QTreeView/QAbstractItemModel用法总结
- Volley使用与解析
- EventBus使用与解析
- RESideMenu使用与解析
- logback使用与解析
- Retrofit使用与解析
- UUID解析与使用
- IntentService解析与使用
- LockSupport解析与使用
- BackupManager的使用与解析
- TimeCacheMap的解析与使用
- RecyclerView的使用与解析
- 【shiro】--- 集成web
- java中的容器变量
- 2075最少拦截系统
- InnoDB undo log解析(一)
- 从面向过程到面向对象
- QAbstractItemModel使用样例与解析
- 8-28 DAIRY
- java提高篇(八)----详解内部类
- Oracle卸载
- DNS
- 2017百度之星程序设计大赛
- 赫夫曼编码
- 《数学之美》—— 读后总结
- Spring Boot中使用MyBatis注解配置详解