转自: http://www.cnblogs.com/Romi/archive/2012/08/08/2628163.html

承接该文http://www.cnblogs.com/Romi/archive/2012/04/16/2452709.html,在该文基础上继续讲解QTreeWidget控件的使用,同时解决该文最后留下的问题。

QTreeWidget是实现树形结构的类,在很多软件中都可以看到类似树形结构的界面。

我做的一个示例如下图,用来处理图像,最顶层节点是图像的路径名,子节点是图像的各个波段,双击各个波段会显示图像各波段的灰度图像,同时还有删除指定节点(父节点和子节点同时删除)的功能。效果如下所示

要完成这样的功能需要注意一下几点:

①.在内存中保存各个节点,当然要在堆上分配内存,删除节点时,除了去除QtreeWidget控件上的节点外,还要讲存储在内存中的节点也要删除,否则会出现内存泄露的问题。

②.节点双击的事件响应,准确定位到是哪个图像的哪个波段。

下面详细叙述。

1.变量

需要有个变量记录图像的路径名,这里定义一个容器,数据类型为QString

QVector<QString> imgFile;

2.定义信号和槽

需要三个槽,

打开菜单:每使用打开菜单打开一幅图像就将该图像的路径名和波段数设计成父节点和子节点添加到QTreeWidget控件中。

删除节点的按钮:删除指定节点(该节点处于高亮状态,即选中状态)

双击某波段:显示该波段的灰度图像。

这里着重讲解与QTreeWidget相关的,因此有关显示图像的内容概不论述。

信号与槽链接如下:

打开菜单      connect(ui.Open,SIGNAL(triggered()),this,SLOT(menu_Open()));

双击某波段   connect(ui.treeWidget,SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),this,SLOT(showSelectedImg(QTreeWidgetItem*,int)));

删除节点      connect(ui.DeleteNode,SIGNAL(clicked()),this,SLOT(btn_DeleteNode()));

3.打开图像(添加节点)

    imgFile.append(fileName);//影像路径添加进容器
QTreeWidgetItem *item=new QTreeWidgetItem(ui.treeWidget,QStringList(QString(fileName)));//添加节点
//添加子节点
for (int i=0;i<rasterNum;i++)
{
QTreeWidgetItem *item1=new QTreeWidgetItem(item,QStringList(QString("Band")+QString::number(i+1)));
item->addChild(item1);
}

其中rasterNum为路径名为fileName的图像的波段数。

这样在QTreewidget部件对象treeWidget中就增加了树节点及其子节点。每次打开都会在树形节点最后面添加。

这里需要提醒一点:这里的QTreewidgetItem指针对象指向的地址都分配在堆上,会不会造成内存泄露呢?因为函数结束后作为局部变量的指针当然是消失了,但保存QTreeWidgetItem节点的内存地址还在,有没有办法在需要的时候将其内存地址释放掉呢,答案是肯定的,将在后面删除节点时论述。

4.双击某波段显示波段图像

        QTreeWidgetItem *parent=item->parent();//获得父节点
if(NULL==parent)
return;
progessBar->setValue(0);//进度条置0
int row=parent->indexOfChild(item);//获得节点在父节点中的行号(从0开始)
QString fileName=parent->text(0);//获得父节点的文本字符(即影像路径)
/* QString->const char* */
QByteArray ba=fileName.toLocal8Bit();
const char* filePath=ba.data();

这里贴出的是找到图像路径和子节点波段的方法,至于显示出图像就是根据图像路径和波段号显示出波段响应灰度图像,该问题不在讨论范畴,略去。

5.删除节点

这里的删除节点不是删除所有节点,而是删除与该节点有关的图像的所有节点,比如,鼠标指向了最开始图中第二个父节点的任意一个子节点,则就将该父节点和所有子节点删除。

    QTreeWidgetItem* item=ui.treeWidget->currentItem();//获得当前节点
if(NULL==item)//没有选择节点
return;
QTreeWidgetItem* parent=item->parent();//获得当前节点的父节点
int index;//top节点的索引号
if(NULL==parent)//item就是top节点
{
QString fileName=item->text(0);//获得top节点的文本字符(即影像路径)
for (int i=0;i<imgFile.size();i++)
{
if (fileName==imgFile.at(i))
{
index=i;
break;
}
}
ui.treeWidget->takeTopLevelItem(index);//去除节点 Removes the top-level item at the given index in the tree and returns it
imgFile.remove(index);//移除容器index处内容 //释放掉存放节点的内存空间
int childCount=item->childCount();//子节点数
for (int i=0;i<childCount;i++)
{
QTreeWidgetItem* childItem=item->child(0);
delete childItem;
childItem=NULL;
}
delete item;
item=NULL;
}
else//parent才是top节点
{
QString fileName=parent->text(0);//获得top节点的文本字符(即影像路径)
for (int i=0;i<imgFile.size();i++)
{
if (fileName==imgFile.at(i))
{
index=i;
break;
}
}
ui.treeWidget->takeTopLevelItem(index);//去除节点 Removes the top-level item at the given index in the tree and returns it
imgFile.remove(index);//移除容器index处内容 //释放掉存放节点的内存空间
int childCount=parent->childCount();//子节点数
for (int i=0;i<childCount;i++)
{
item=parent->child(0);
delete item;
item=NULL;
}
delete parent;
parent=NULL;
}

主要方法就是根据图像路径名获得图像在top节点中的索引号,然后将top节点及其子节点删除,采用takeTopLevelItem(index)方法可以把treeWidget中的所因为index的节点去除掉,注意这里只是将节点从treeWidget中去除掉,其节点(父节点+子节点)仍然存在内存中,所以还要讲内存中的地址也要释放掉,否则就会出现所谓的内存泄露的问题。所采用的方法时使用QTreeWidgetItem指针找到存放节点的内存地址,然后将其delete掉,如此就释放掉内存空间了(有疑问的可以跟踪调试下),一定注意将要删除的节点全部delete掉,先释放子节点内存,再释放父节点内存。

还需要注意的是,每清除掉一个子节点的内存空间,对应父节点就会失去该子节点,因此每次都是清理掉父节点索引为0的子节点,即获得child(0)的子节点。此外不要忘了保存图像路径的向量imgFile中也要去除对应的索引内容。

总结

以上给出的是实现功能的核心实现部分,并非完整的程序,其他未论述的都是与QTreeWidget该控件无关的了。上述方法可移植性强,可以用到有类似需求的地方。

Qt QTreeWidget节点的添加+双击响应+删除详解的更多相关文章

  1. Qt QTreeWidget节点的添加+双击响应+删除详解(转)

    QTreeWidget是实现树形结构的类,在很多软件中都可以看到类似树形结构的界面. 我做的一个示例如下图,用来处理图像,最顶层节点是图像的路径名,子节点是图像的各个波段,双击各个波段会显示图像各波段 ...

  2. Elasticsearch-2.4.3的3节点安装(多种方式图文详解)(含 head、kopf、marvel、shield和watcher插件安装和使用)

    前提: Elasticsearch-2.4.3的下载(图文详解) Elasticsearch-2.4.3的单节点安装(多种方式图文详解) 我这里,以192.168.80.10(HadoopMaster ...

  3. 节点地址的函数list_entry()原理详解

    本节中,我们继续讲解,在linux2.4内核下,如果通过一些列函数从路径名找到目标节点. 3.3.1)接下来查看chached_lookup()的代码(namei.c) [path_walk()> ...

  4. 【Qt】Qt Quick 之 QML 与 C++ 混合编程详解

    Qt Quick 之 QML 与 C++ 混合编程详解 - CSDN博客   专栏:Qt Quick简明教程 - CSDN博客   .

  5. jmeter --响应断言详解

    jmeter --响应断言详解 响应断言 :对服务器的响应进行断言校验 (1)应用范围: main sample and sub sample, main sample only , sub-samp ...

  6. Jmeter接口之响应断言详解

    响应断言 : 对服务器的响应进行断言校验 Apply to 应用范围: main sample and sub sample, main sample only , sub-sample only , ...

  7. 『动善时』JMeter基础 — 29、JMeter响应断言详解

    目录 1.JMeter断言介绍 2.响应断言组件界面详解 3.响应断言组件的使用 (1)测试计划内包含的元件 (2)登陆接口请求界面内容 (3)响应断言界面内容 (4)查看运行结果 (5)断言结果组件 ...

  8. RB-Tree删除详解

    红黑树的删除操作较于插入操作,情况更为复杂: 考虑到红黑节点的差异性,我们在此通过红黑节点来考虑这个问题,即仅仅通过要删除的节点是红节点,还是黑节点来讨论不同的情况: 1  删除的红节点为叶子结点(此 ...

  9. Elasticsearch-2.4.3的单节点安装(多种方式图文详解)

    前提: Elasticsearch-2.4.3的下载(图文详解) 1.新建es安装目录 [root@djt002 local]# mkdir elasticsearch [root@djt002 lo ...

随机推荐

  1. [转]libevent 环境配置

    libevent 据说是IO复用的好东西.所以今天来耍耍. 1. 从官网下载源代码:http://libevent.org/,最新的版本已达到2.0. 2. 先把ubuntu系统自带的libevent ...

  2. 【BZOJ1053】[HAOI2007]反素数ant 暴力

    [BZOJ1053][HAOI2007]反素数ant Description 对于任何正整数x,其约数的个数记作g(x).例如g(1)=1.g(6)=4.如果某个正整数x满足:g(x)>g(i) ...

  3. Spec Explorer 工具学习

    基础概念:http://blogs.msdn.com/b/sechina/archive/2009/12/28/test.aspx 在线教程:http://blogs.msdn.com/b/sechi ...

  4. DumpBinary

    stdafx.h #include "targetver.h" #include <stdio.h> #include <tchar.h> #include ...

  5. MySQL中Btree和Hash的局限小结

    在索引中,Btree索引和Hash索引的局限性,在这里粗略罗列一下 1 Btree局限 B-树中的节点都是顺序存储的,所以可以利用索引进行查找(找某些值),也可以对查询结果进行ORDER BY(注意O ...

  6. T-SQL怎样提高数据库性能

    总结: 1.书写问题 2.表连接方式 3.索引的抉择 4.执行计划之参数嗅探 5.子查询与表连接的效率 6.临时表.CTE.表变量的选择 7.常用sp与select的缓存命中 8.锁(善用nolock ...

  7. 用django写个CMS系统

    上一篇介绍过django自带的flatpages,能够做简单的CMS.但是对于我们的真正的工作中的使用意义并不大.还是自己动手写一个吧. 不用说,一定是先从models开始的: from django ...

  8. FarBox的使用经历

    新年伊始,一个崭新的开始,我的博客也有个新的起点.怎么会有这个想法呢?个人觉得这是程序员那颗不安分的心开始躁动了(其实就是开始作了~~哈哈,开个玩笑). 更佳界面.更流畅的操作.更方便的查看.更炫酷动 ...

  9. java PinYinUtils 拼音工具类

    package com.sicdt.library.core.utils; import java.util.HashSet; import java.util.Set; import net.sou ...

  10. NAS、SAN、DAS 说明

    NAS 说明 1.NAS(Network Attached Storage:网络附属存储) 2.NAS 是一种采用直接与网络介质相连的特殊设备实现数据存储的机制. 3.NAS本身能够支持多种协议(如N ...