QAbstractItemModel使用样例与解析(Model::index使用了createIndex,它会被销毁吗?被销毁了,因为栈对象出了括号就会被销毁)
参考: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;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
实现几排几列表格情形的例子:
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){}
};
1
2
3
4
5
6
7
生成如下的这种界面:两个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)
---------------------
作者:春夜喜雨
来源:CSDN
原文:https://blog.csdn.net/chunyexiyu/article/details/77657624
版权声明:本文为博主原创文章,转载请附上博文链接!
void wokr()
{
QModelIndex index = model.getIndex();
...
...
return;
// 局部变量,函数退出时自动回收。
} std::string func()
{
return "";
}
你需要管返回值谁释放嘛? 奇怪的问题 std::string* func()
{
return new std::string("");
}
但是这个你就要关心了
QAbstractItemModel使用样例与解析(Model::index使用了createIndex,它会被销毁吗?被销毁了,因为栈对象出了括号就会被销毁)的更多相关文章
- Sakila——MySQL样例数据库解析(已经迁移)
一.Introduction Sakila可以作为数据库设计的参考,也可作为实验数据.我是用作数据仓库和ODI学习的实验数据. The Sakila sample database was devel ...
- jsp页面样例及解析
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...
- Java 连接 Hive的样例程序及解析
以后编程基于这个样例可节省查阅API的时间. private static String driverName = "org.apache.hadoop.hive.jdbc.HiveDriv ...
- 让你提前认识软件开发(19):C语言中的协议及单元測试演示样例
第1部分 又一次认识C语言 C语言中的协议及单元測试演示样例 [文章摘要] 在实际的软件开发项目中.常常要实现多个模块之间的通信.这就须要大家约定好相互之间的通信协议,各自依照协议来收发和解析消息. ...
- Spring MVC使用样例
Spring MVC使用样例 步骤1:添加Spring的相关依赖 1 <dependency> 2 3 <groupId>com.alibaba.external</gr ...
- SNF快速开发平台MVC-各种级联绑定方式,演示样例程序(包含表单和表格控件)
做了这么多项目,经常会使用到级联.联动的情况. 如:省.市.县.区.一级分类.二级分类.三级分类.仓库.货位. 方式:有表单需要做级联的,还是表格行上需要做级联操作的. 实现:实现方法也有很多种方式. ...
- 10分钟理解Android数据库的创建与使用(附具体解释和演示样例代码)
1.Android数据库简单介绍. Android系统的framework层集成了Sqlite3数据库.我们知道Sqlite3是一种轻量级的高效存储的数据库. Sqlite数据库具有以下长处: (1) ...
- 最简单的视音频播放演示样例3:Direct3D播放YUV,RGB(通过Surface)
===================================================== 最简单的视音频播放演示样例系列文章列表: 最简单的视音频播放演示样例1:总述 最简单的视音频 ...
- Yii学习笔记之二(使用gii生成一个简单的样例)
1. 数据库准备 (1) 首先我们建一数据库 yii2test 并建立一张表例如以下: DROP TABLE IF EXISTS `posts`; CREATE TABLE `posts` ( `po ...
随机推荐
- 查询Oracle正在执行的sql语句及kill被锁的表
查询Oracle正在执行的sql语句及执行该语句的用户SELECT b.sid oracleID, b.username 登录Oracle用户名, b.serial#, spid 操作系统ID, pa ...
- 一步一步学习FastJson1.2.47远程命令执行漏洞
本文首发于先知:https://xz.aliyun.com/t/6914 漏洞分析 FastJson1.2.24 RCE 在分析1.2.47的RCE之前先对FastJson1.2.24版本中的RCE进 ...
- MyBatis错误:The server time zone value '?泄???????' is unrecognized or represents more t
原文地址:http://blog.csdn.net/oppo5630/article/details/52162783 解决java.sql.SQLException: The server time ...
- 学习ArrayList的扩容机制
基于jdk8 1.首先我们看new ArrayList中 public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDA ...
- Linux嵌入式学习过程(转载)
嵌入式专业是一门实践性非常强的学科,只有多动手,多实践,多编程,多调试,多看书,多思考才能真正掌握好嵌入式开发技术.那么,如何从零开始学习嵌入式开发技术, 进入嵌入式开发大门呢,笔者根据自己的嵌入式学 ...
- 路由传值及获取参数,路由跳转,路由检测,this.$route.query和this.$route.params接收参数,HttpGet请求拼接url参数
配置动态路由参数id: routes: [ // 动态路径参数 以冒号开头 { path: '/user/:id', component: User } ] html路由跳转: <router- ...
- Qt编写安防视频监控系统10-视频轮询
一.前言 视频轮询在视频监控系统中是一个基础的核心功能,尤其是上了大屏以后,这个功能是必须的,根据预先设定的轮询间隔逐个加载视频到预先设定的通道画面数中,轮询间隔.轮询画面数.轮询采用的码流类型(主码 ...
- BSD process name correspondlng to current thread: knernel_task Mac OS version Not yet set
网上查了一大堆,没有一个靠谱的, 百度,以说黑苹果装系统最容易出现这个,这个让我开始怀疑公司给我们的所谓外观的iMac是黑苹果了,因为一直很卡,比上家公司的真黑苹果还卡. 谷歌,有说重置BIOS电池的 ...
- pycharm连接linux版python
1.建立连接 2.测试连接 3.同步目录 4.查看同步的目录 5.设置永久同步目录 6.设置连接 可以看到添加进来了 参照文档: https://www.cnblogs.com/xiao-apple3 ...
- 1-3 RHEL7操作系统的安装
RHEL7操作系统的安装 本节所讲内容: q RHEL7.2操作系统的安装 第1章 RHEL7系统安装 1.1 安装软件准备: 需要的软件如下: Vmware workstation 12(含注册码 ...