在上一篇博文《C/C++ Qt TreeWidget 单层树形组件应用》中给大家演示了如何使用TreeWidget组件创建单层树形结构,并给这个树形组件增加了右键菜单功能,接下来将继续延申树形组件的使用,并实现对树形框多节点的各种操作。

常用树形框节点间的操作方法如下:

  • 节点遍历
  • 初始化节点
  • 单击双击节点
  • 添加根节点
  • 添加子节点
  • 修改选中节点
  • 删除选中节点
  • 枚举全部节点
  • 枚举选中节点
  • 获取节点子节点

简单的节点遍历: 首先我们还是使用TreeView组件实现一个简单的多层嵌套树结构,代码运行后,首先循环设置3个外层节点,接着循环内层节点,并将内层中的QStandardItem追加到外层上面。

#include "mainwindow.h"
#include "ui_mainwindow.h" #include <QTreeView>
#include <QStandardItemModel> // By: LyShark
// https://www.cnblogs.com/lyshark
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
ui->setupUi(this); QStandardItemModel *tree = new QStandardItemModel(0,3,this); ui->treeView->setColumnWidth(0,50); // 设置第1列长度
ui->treeView->setColumnWidth(1,200); // 设置第2列长度
ui->treeView->setColumnWidth(2,200); // 设置第3列长度 tree->setHeaderData(0, Qt::Horizontal, tr("序号"));
tree->setHeaderData(1, Qt::Horizontal, tr("姓名"));
tree->setHeaderData(2, Qt::Horizontal, tr("年龄")); ui->treeView->setModel(tree); for (int i = 0; i < 4; ++i)
{
// 设置3个外层节点
QList<QStandardItem *> items;
for (int i = 0; i < 3; ++i)
{
QStandardItem *item = new QStandardItem(QString("%0").arg(i)); if (0 == i)
item->setCheckable(true); items.push_back(item);
}
tree->appendRow(items); // 设置内层
for (int i = 0; i < 2; ++i)
{
QList<QStandardItem *> childItems;
for (int i = 0; i < 3; ++i)
{
QStandardItem *item = new QStandardItem(QString("lyshark"));
if (0 == i)
item->setCheckable(true);
childItems.push_back(item);
}
items.at(0)->appendRow(childItems);
}
}
} MainWindow::~MainWindow()
{
delete ui;
}

代码运行效果如下:

初始化树形节点: 首先在开始操作元素之前,我们可以在MainWindow::MainWindow中对树形节点进行简单的初始化,插入几个测试节点.

#include "mainwindow.h"
#include "ui_mainwindow.h" #include <iostream>
#include <QTreeWidgetItem>
#include <QString> // By: LyShark
// https://www.cnblogs.com/lyshark
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->treeWidget->clear(); // 设置QTreeWidget的列数
ui->treeWidget->setColumnCount(1);
// 设置QTreeWidget标题隐藏
ui->treeWidget->setHeaderHidden(true); // 创建QTreeWidget的朋友节点,父节点是tree
QTreeWidgetItem *Friend = new QTreeWidgetItem(ui->treeWidget,QStringList(QString("朋友")));
Friend->setIcon(0,QIcon(":/image/4.ico")); // 添加一个图标
Friend->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable
| Qt::ItemIsEnabled | Qt::ItemIsAutoTristate);
Friend->setCheckState(0,Qt::Checked); // 给Friend添加一个子节点frd
QTreeWidgetItem *frd = new QTreeWidgetItem(Friend);
frd->setText(0,"www.lyshark.com");
frd->setIcon(0,QIcon(tr(":/image/1.ico")));
frd->setCheckState(0,Qt::Checked); // 默认选中状态 QTreeWidgetItem *frs = new QTreeWidgetItem(Friend);
frs->setText(0,"cdn.lyshark.com");
frs->setIcon(0,QIcon(tr(":/image/1.ico")));
frs->setCheckState(0,Qt::Unchecked); // 默认未选中 // ----------------------------------------------------------
// 创建名叫同学节点,父节点同样是tree
QTreeWidgetItem * ClassMate = new QTreeWidgetItem(ui->treeWidget,QStringList(QString("同学")));
ClassMate->setIcon(0,QIcon(":/image/5.ico")); // 添加一个图标
ClassMate->setCheckState(0,Qt::Checked); // 默认选中 //Fly是ClassMate的子节点
QTreeWidgetItem *Fly = new QTreeWidgetItem(QStringList(QString("nas.lyshark.com")));
Fly->setIcon(0,QIcon(tr(":/image/2.ico")));
//创建子节点的另一种方法
ClassMate->addChild(Fly);
Fly->setCheckState(0,Qt::Checked); // 设置为选中 QTreeWidgetItem *Fls = new QTreeWidgetItem(QStringList(QString("lyshark.cnblogs.com")));
Fls->setIcon(0,QIcon(tr(":/image/2.ico")));
ClassMate->addChild(Fls);
Fls->setCheckState(0,Qt::Checked); // 设置为选中 // ----------------------------------------------------------
// 陌生人单独一栏
QTreeWidgetItem *Strange = new QTreeWidgetItem(true);
Strange->setText(0,"陌生人");
Strange->setIcon(0,QIcon(":/image/6.ico")); // 添加一个图标 ui->treeWidget->addTopLevelItem(ClassMate);
ui->treeWidget->addTopLevelItem(Strange); // 增加文本到编辑框
ui->plainTextEdit->appendPlainText("hello lyshark"); //展开QTreeWidget的所有节点
//ui->treeWidget->expandAll();
//ui->treeWidget->resize(271,401);
} MainWindow::~MainWindow()
{
delete ui;
}

代码运行效果如下:

单击双击节点反馈: 当我们将鼠标停靠在指定节点内并点击时,我们需要触发treeWidget_itemDoubleClicked属性让其反馈该行标题等基本属性.

// 当我们双击指定的成员时获取到该成员的名字
void MainWindow::on_treeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column)
{
QString str = item->text(column);
std::cout << str.toStdString().data() << std::endl;
ui->plainTextEdit->appendPlainText(str.toStdString().data());
} // 当我们单击指定成员时获取数据
void MainWindow::on_treeWidget_itemClicked(QTreeWidgetItem *item, int column)
{
QString str = item->text(column);
std::cout << str.toStdString().data() << std::endl;
ui->plainTextEdit->appendPlainText(str.toStdString().data());
}

代码运行效果如下:

添加 父节点/子节点: 通过代码的方式当点击on_pushButton_clicked时分别实现增加一个父节点和一个子节点的功能。

// 单击按钮添加新的父节点
void MainWindow::on_pushButton_clicked()
{
QString NodeText = "新的父节点";
QTreeWidgetItem *item = new QTreeWidgetItem(true);
item->setText(0,NodeText);
item->setIcon(0,QIcon(":/image/7.ico"));
ui->treeWidget->addTopLevelItem(item);
} // 单击按钮添加子节点
void MainWindow::on_pushButton_4_clicked()
{
QTreeWidgetItem * item= ui->treeWidget->currentItem();
if(item!=NULL)
AddTreeNode(item,"新子节点","新子节点");
else
AddTreeRoot("新子节点","新子节点");
}

代码运行效果如下:

删除选中节点: 首先选中要删除的指定节点,然后可以对该节点进行删除操作,删除子节点直接移除即可,删除父节点需要连同内部子节点一并删掉。

// 删除选中的节点
void MainWindow::on_pushButton_3_clicked()
{
QTreeWidgetItem *currentItem = ui->treeWidget->currentItem();
if(currentItem == NULL)
return; // 如果没有父节点则直接删除
if(currentItem->parent() == NULL)
{
delete ui->treeWidget->takeTopLevelItem(ui->treeWidget->currentIndex().row());
std::cout << ui->treeWidget->currentIndex().row() << std::endl;
}
else
{
// 如果有父节点就要用父节点的takeChild删除节点
delete currentItem->parent()->takeChild(ui->treeWidget->currentIndex().row());
}
}

代码运行效果如下:

修改指定节点名称: 单击后将指定节点修改为Modify并将图标设置为新的

// 修改节点
// By: LyShark
// https://www.cnblogs.com/lyshark
void MainWindow::on_pushButton_2_clicked()
{
// 得到当前节点
QTreeWidgetItem *currentItem = ui->treeWidget->currentItem();
if(currentItem == NULL)
return;
// 修改选中项
for(int x=0;x<currentItem->columnCount();x++)
{
currentItem->setText(x,tr("Modify") + QString::number(x));
currentItem->setIcon(x,QIcon(":/image/1.ico"));
}
}

代码运行效果如下:

枚举所有节点元素: 枚举当前Tree中的所有节点元素,并将结果输出到右侧编辑框内。

// 枚举所有节点
// By: LyShark
// https://www.cnblogs.com/lyshark
// 枚举所有节点
void MainWindow::on_pushButton_5_clicked()
{
// 获取到全部的根节点数量
int size = ui->treeWidget->topLevelItemCount();
QTreeWidgetItem *child;
for(int x=0;x<size;x++)
{
// 输出所有父节点
child = ui->treeWidget->topLevelItem(x);
std::cout << "all root = "<< child->text(0).toStdString().data() << std::endl;
ui->plainTextEdit->appendPlainText(child->text(0).toStdString().data()); // 得到所有子节点计数
int childCount = child->childCount();
// std::cout << "all child count = " << childCount << std::endl; // 输出根节点下面的子节点
for(int y=0;y<childCount;++y)
{
QTreeWidgetItem *grandson = child->child(y);
std::cout << "--> sub child = "<< grandson->text(0).toStdString().data() << std::endl;
ui->plainTextEdit->appendPlainText(grandson->text(0).toStdString().data());
}
}
}

代码运行效果如下:

枚举选中节点元素: 枚举当前Tree中选中节点的元素,并将结果输出到右侧编辑框内。

// 枚举所有的 【选中】节点
// https://www.cnblogs.com/lyshark
void MainWindow::on_pushButton_7_clicked()
{
// 获取到全部的根节点数量
int size = ui->treeWidget->topLevelItemCount();
QTreeWidgetItem *child;
for(int x=0;x<size;x++)
{
// 输出所有父节点
child = ui->treeWidget->topLevelItem(x); // 得到所有子节点计数
int childCount = child->childCount(); // 输出根节点下面的子节点
for(int y=0;y<childCount;++y)
{
QTreeWidgetItem *grandson = child->child(y);
// 判断是否选中,如果选中输出父节点与子节点
if(Qt::Checked == grandson->checkState(0))
{
std::cout << "root -> " << child->text(0).toStdString().data()
<< "--> sub child = "<< grandson->text(0).toStdString().data() << std::endl; ui->plainTextEdit->appendPlainText(grandson->text(0).toStdString().data());
}
}
}
}

代码运行效果如下:

获取选中子节点的父节点: 获取子节点的父节点ID,然后根据ID得到子节点名字。

void MainWindow::on_pushButton_6_clicked()
{
// 取所有的父节点
QTreeWidgetItem *currentItem = ui->treeWidget->currentItem()->parent();
int root_count = ui->treeWidget->indexOfTopLevelItem(currentItem);
std::cout << "root Count = " << root_count << std::endl;
if(root_count != -1)
{
// 指定序号对应的父节点名字
QTreeWidgetItem *child; child = ui->treeWidget->topLevelItem(root_count);
std::cout << "root name= "<< child->text(0).toStdString().data() << std::endl; ui->plainTextEdit->appendPlainText(child->text(0).toStdString().data());
}
}

代码运行效果如下:

C/C++ Qt TreeWidget 嵌套节点操作技巧的更多相关文章

  1. 分享基于.NET动态编译&Newtonsoft.Json封装实现JSON转换器(JsonConverter)原理及JSON操作技巧

    看文章标题就知道,本文的主题就是关于JSON,JSON转换器(JsonConverter)具有将C#定义的类源代码直接转换成对应的JSON字符串,以及将JSON字符串转换成对应的C#定义的类源代码,而 ...

  2. 深度解析JQuery Dom元素操作技巧

    深度解析JQuery Dom元素操作技巧 DOM是一种与浏览器.平台.语言无关的接口,使用该接口可以轻松访问页面中所有的标准组件,这篇文章给大家介绍了JQuery dom元素操作方法,写的十分的全面细 ...

  3. 用ArcGIS?37个Arcmap常用操作技巧可能帮到您

    1. 要素的剪切与延伸 实用工具 TASK 任务栏 Extend/Trim feature 剪切所得内容与你画线的方向有关. 2. 自动捕捉跟踪工具 点击Editor工具栏中Snapping来打开Sn ...

  4. 深入理解DOM节点操作

    × 目录 [1]创建节点 [2]插入节点 [3]移除节点[4]替换节点[5]复制节点 前面的话 一般地,提起操作会想到“增删改查”这四个字,而DOM节点操作也类似地对应于此,接下来将详细介绍DOM的节 ...

  5. 用Excel做出比肩任务管理软件的操作技巧

    用Excel做出比肩任务管理软件的操作技巧 在项目管理中,网上有各种各样的工具可以选择,到底用哪个,曾一度困扰着我.我是一个有轻度强迫症的人,总是喜欢试用各种各样的系统,以比较他们之间的不同,试图选择 ...

  6. 深入学习jQuery节点操作

    × 目录 [1]创建节点 [2]插入节点 [3]删除节点[4]复制节点[5]替换节点[6]包裹节点 前面的话 DOM节点操作包括创建节点.插入节点.移除节点.替换节点和复制节点.jQuery也有类似的 ...

  7. 第32课 Qt中的文件操作

    1. Qt的中IO操作 (1)Qt中IO操作的处理方式 ①Qt通过统一的接口简化了文件和外部设备的操作方式 ②Qt中的文件被看作一种特殊的外部设备 ③Qt中的文件操作与外部设备的操作相同 (2)IO操 ...

  8. Query节点操作,jQuery插入节点,jQuery删除节点,jQuery Dom操作

    一.创建节点 var box = $('<div>节点</div>'); //创建一个节点,或者var box = "<div>节点</div> ...

  9. 第6章 DOM节点操作

    一.创建节点 为了使页面更加智能化,有时我们想动态的在 html 结构页面添加一个元素标签,那么 在插入之前首先要做的动作就是:创建节点. varbox=$('<div id="box ...

随机推荐

  1. Windows用cmd编译运行C程序

    在Windows环境下用命令行编译运行程序 浙江大学-C语言程序设计进阶 配置gcc 准备一个Dev-cpp 找到gcc.exe所在目录 Dev-Cpp\MinGW64\bin 地址栏右键将地址复制为 ...

  2. PG集群(PostgreSql环境)搭建

    centos PG集群搭建 一.安装PG 1.安装之前首先查看软件是否已经安装 rpm -qa | grep postgresql #若存在,需要卸载使用 yum remove postgresql ...

  3. 使用vue-cli+webpack搭建vue开发环境

    在这里我真的很开心,好久没有用过博客,今天突然看到了我的博客有不少人看过,虽然没有留下脚印,但是还是激起了我重新拿起博客的信心,感谢大家. 在这里我们需要首先下载node,因为我们要用到npm包下载, ...

  4. 23.合并k个有序链表

    合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [   1->4->5,   1->3->4,   2->6 ] 输出: 1-&g ...

  5. Java:阻塞队列

    Java:阻塞队列 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 1. 概述 概念 队列 队列就可以想成是一个数组,从一头进入,一头出去,排队买饭 阻塞队列 B ...

  6. Spring Authorization Server的使用

    Spring Authorization Server的使用 一.背景 二.前置知识 三.需求 四.核心代码编写 1.引入授权服务器依赖 2.创建授权服务器用户 3.创建授权服务器和客户端 五.测试 ...

  7. Prometheus重新标记

    Prometheus重新标记 一.背景 二.简化的指标抓取的生命周期 1.配置参数详解 1.`action:`存在的值 1.替换标签值 2.删除指标 3.创建或删除标签 2.删除标签注意事项 3.几个 ...

  8. Ajax配合后端实现Excel的导出

    一.需求 在我们的日常开发中,可能经常需要遇到excel的导出,以往excel的导出服务器端都是使用的 GET 方法,但是某些情况下,服务器端只能使用 POST 方法,那么我们有没有好的方法实现exc ...

  9. 【Azure Redis 缓存】Windows版创建 Redis Cluster 实验 (精简版)

    简介 学习Redis Cluster的第一步,即本地搭建Redis Cluster.但是在Redis的官方文档中,是介绍在Linux系统中搭建Redis Cluster.本文主要介绍在Windows系 ...

  10. python 修饰器(decorator)

    转载:Python之修饰器 - 知乎 (zhihu.com) 什么是修饰器,为什么叫修饰器 修饰器英文是Decorator, 我们假设这样一种场景:古老的代码中有几个很是复杂的函数F1.F2.F3.. ...