Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍
TreeWidget
树形选择组件的常用方法及灵活运用。
QTreeWidget
是 Qt 中的树形控件组件,用于显示树形结构的数据。它继承自
QTreeView
和
QTreeWidget
,提供了一个方便的方式来展示和编辑包含层次结构数据的项目。
以下是
QTreeWidget
类的一些常用方法,说明和概述:
addTopLevelItem(QTreeWidgetItem *item)
向树中添加一个顶级项目。
addTopLevelItems(const QList<QTreeWidgetItem *> &items)
向树中添加多个顶级项目。
clear()
清除树中的所有项目。
currentItem()
返回当前选择的项目。
currentIndex()
返回当前选择的项目的模型索引。
editItem(QTreeWidgetItem *item, int column)
进入编辑模式以编辑给定项目的指定列。
headerItem()
返回树的标题项目,该项目可用于设置标题标签。
invisibleRootItem()
返回树的不可见根项目。
itemAbove(QTreeWidgetItem *item)
返回给定项目的上面一个项目。
itemBelow(QTreeWidgetItem *item)
返回给定项目的下面一个项目。
setCurrentItem(QTreeWidgetItem *item)
设置当前选择的项目。
topLevelItem(int index)
返回树中给定索引的顶级项目。
topLevelItemCount()
返回树的顶级项目的数量。
insertTopLevelItem(int index, QTreeWidgetItem *item)
在给定索引处插入一个顶级项目。
insertTopLevelItems(int index, const QList<QTreeWidgetItem *> &items)
在给定索引处插入多个顶级项目。
takeTopLevelItem(int index)
从树中移除给定索引处的顶级项目,并返回该项目的指针。
scrollToItem(QTreeWidgetItem *item, QAbstractItemView::ScrollHint hint = EnsureVisible)
滚动树以确保给定项目可见。
sortItems(int column, Qt::SortOrder order = Qt::AscendingOrder)
对树中的项目进行排序。
findItems(const QString &text, Qt::MatchFlags flags, int column = 0)
查找树中包含指定文本的项目。
这只是
QTreeWidget
类的一小部分方法。你可以查阅
官方文档
以获取完整的方法列表,以及这些方法的详细说明。
首先我们来绘制一下
UI
界面,由于该节点同时具备编辑功能所以实现起来要稍微复杂一些,我们分别在最左侧放置一个
TreeWidget
组件,在中间放置不同的
PushButton
组件,最后是一个
plainTextEdit
组件用来接收反馈,如下图所示;
1.1 初始化组件
如下代码是在 Qt 中使用
QTreeWidget
初始化一个树形结构,其中包含了朋友、同学和陌生人等不同分类的节点。
以下是概述:
QTreeWidget
:
设置
QTreeWidget
的一些基本属性,包括列数、标题的隐藏等。
QTreeWidgetItem
创建一个朋友节点,并设置图标、选择状态等属性。然后添加两个子节点 “老张” 和 “老王”,分别设置图标和选择状态。
QTreeWidgetItem
直接创建一个陌生人节点,并设置文本和图标。
QTreeWidget
中:
使用
addTopLevelItem
将 “同学” 和 “陌生人” 节点添加到
QTreeWidget
的顶级。
expandAll
展开所有节点,使其在初始化时可见。
QTreeWidget
的大小:
使用
resize
设置
QTreeWidget
的大小。
这段代码的主要功能是创建一个包含不同分类和子节点的树形结构,每个节点可以有不同的图标、文本和选择状态。在展示的树形结构中,朋友和同学节点有子节点,而陌生人节点没有子节点。这个示例展示了
QTreeWidget
用于创建层次结构的基本用法。
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) |
代码运行后可动态对左侧组件进行初始化,并增加应有的父节点与子节点,如下图;
1.2 添加根节点
如下槽函数,其核心功能是在
QTreeWidget
中添加一个新的顶级父节点,并在
QPlainTextEdit
中添加一行文本记录。
以下是概述:
QString NodeText = "新的父节点";
设置新父节点的文本。
QTreeWidgetItem
:
使用
QTreeWidgetItem
的构造函数创建一个新的顶级父节点,并设置其文本和图标。
QTreeWidget
中:
使用
ui->treeWidget->addTopLevelItem(item);
将新的顶级父节点添加到
QTreeWidget
中。
QPlainTextEdit
中:
使用
ui->plainTextEdit->appendPlainText("添加新的父节点");
将一行文本记录添加到
QPlainTextEdit
中,用于记录操作。
这段代码的作用是在点击按钮时,在
QTreeWidget
中添加一个新的顶级父节点,并在
QPlainTextEdit
中记录这一操作。这样可以用于在界面上动态添加树节点,并记录相关的操作信息。
void MainWindow::on_pushButton_add_clicked() |
运行后通过点击添加根节点按钮,每次则可以生成一个根,如下图;
1.3 添加子节点
如下槽函数,其核心功能是在
QTreeWidget
中添加新的子节点,并在
QPlainTextEdit
中添加一行文本记录。
以下是概述:
QTreeWidgetItem * item= ui->treeWidget->currentItem();
获取当前在
QTreeWidget
中选择的节点。
if(item!=NULL)
条件判断,如果存在选择的节点,则调用
AddTreeNode
函数添加子节点;否则,调用
AddTreeRoot
函数添加新的根节点。
-
如果存在选择的节点,调用
AddTreeNode(item,"新子节点","新子节点");
添加一个新的子节点,其文本和图标分别为 “新子节点”。 -
如果没有选择的节点,调用
AddTreeRoot("新子节点","新子节点");
添加一个新的根节点,其文本和图标同样为 “新子节点”。 -
记录操作到
QPlainTextEdit
中: 使用ui->plainTextEdit->appendPlainText("添加新的子节点");
将一行文本记录添加到QPlainTextEdit
中,用于记录操作。 -
获取当前选中的节点:
使用
QTreeWidgetItem *currentItem = ui->treeWidget->currentItem();
获取当前在QTreeWidget
中选择的节点。 -
判断是否存在选择的节点:
使用
if(currentItem == NULL)
条件判断,如果没有选择的节点,则直接返回。 -
修改选中节点的文本和图标:
使用
for
循环遍历节点的所有列,通过setText
修改每一列的文本为 “Modify” 加上列索引的字符串,通过setIcon
修改每一列的图标为特定的图标。 -
记录操作到
QPlainTextEdit
中: 使用ui->plainTextEdit->appendPlainText("修改节点名");
将一行文本记录添加到QPlainTextEdit
中,用于记录操作。 -
获取当前选中的节点:
使用
QTreeWidgetItem *currentItem = ui->treeWidget->currentItem();
获取当前在QTreeWidget
中选择的节点。 -
判断是否存在选择的节点:
使用
if(currentItem == NULL)
条件判断,如果没有选择的节点,则直接返回。 -
判断是否为顶级父节点:
使用
if(currentItem->parent() == NULL)
条件判断,如果当前节点没有父节点(即为顶级父节点),则使用ui->treeWidget->takeTopLevelItem
删除该节点。 -
如果有父节点,使用父节点的
takeChild
删除子节点: 使用delete currentItem->parent()->takeChild(ui->treeWidget->currentIndex().row());
删除当前节点。这种情况下,要使用父节点的takeChild
方法,因为直接删除会导致父节点无法正确管理子节点。 -
记录操作到
QPlainTextEdit
中: 使用ui->plainTextEdit->appendPlainText("删除一个节点");
将一行文本记录添加到QPlainTextEdit
中,用于记录操作。 -
获取全部的根节点数量:
使用
int size = ui->treeWidget->topLevelItemCount();
获取顶级父节点的数量。 -
遍历所有根节点:
使用
for
循环遍历每一个根节点,通过ui->treeWidget->topLevelItem(x)
获取当前的根节点。 -
输出所有根节点:
使用
child->text(0).toStdString().data()
输出当前根节点的文本信息,并将其输出到标准输出流。 -
遍历根节点下的子节点:
使用内层
for
循环遍历当前根节点下的所有子节点,通过child->child(y)
获取子节点。 -
输出子节点:
使用
grandson->text(0).toStdString().data()
输出当前子节点的文本信息,并将其输出到标准输出流。 -
记录操作到
QPlainTextEdit
中: 使用ui->plainTextEdit->appendPlainText("枚举所有节点");
将一行文本记录添加到QPlainTextEdit
中,用于记录操作。 -
获取全部的根节点数量:
使用
int size = ui->treeWidget->topLevelItemCount();
获取顶级父节点的数量。 -
遍历所有根节点:
使用
for
循环遍历每一个根节点,通过ui->treeWidget->topLevelItem(x)
获取当前的根节点。 -
遍历根节点下的子节点:
使用内层
for
循环遍历当前根节点下的所有子节点,通过child->child(y)
获取子节点。 -
判断是否选中:
使用
if(Qt::Checked == grandson->checkState(0))
判断当前子节点是否被选中。 - 输出选中节点信息: 如果子节点被选中,输出当前根节点与子节点的文本信息,并将信息输出到标准输出流。
-
记录操作到
QPlainTextEdit
中: 使用ui->plainTextEdit->appendPlainText("枚举所有选中节点");
将一行文本记录添加到QPlainTextEdit
中,用于记录操作。 -
获取当前选中节点的父节点:
使用
QTreeWidgetItem *currentItem = ui->treeWidget->currentItem()->parent();
获取当前选中节点的父节点。 -
获取父节点在顶级节点中的序号:
使用
int root_count = ui->treeWidget->indexOfTopLevelItem(currentItem);
获取父节点在顶级节点中的序号。 -
判断是否存在父节点:
使用
if(root_count != -1)
条件判断,如果存在父节点,执行下面的操作;否则,直接返回。 -
获取指定序号对应的父节点:
使用
child = ui->treeWidget->topLevelItem(root_count);
获取指定序号对应的父节点。 -
输出父节点的序号和名字:
使用
std::cout << "root Count = " << root_count << std::endl;
输出父节点在顶级节点中的序号,以及std::cout << "root name= "<< child->text(0).toStdString().data() << std::endl;
输出父节点的名字。 -
记录操作到
QPlainTextEdit
中: 使用ui->plainTextEdit->appendPlainText("获取父节点ID");
将一行文本记录添加到QPlainTextEdit
中,用于记录操作。
这段代码的作用是在点击按钮时,根据用户当前选择的节点状态,在
QTreeWidget
中添加新的子节点或新的根节点,并记录这一操作到
QPlainTextEdit
中。
QTreeWidgetItem * MainWindow::AddTreeRoot(QString name,QString desc) |
子节点的添加依赖于封装好的两个
AddTreeNode
函数,通过调用后则可以在父节点上添加子节点,如下图;
1.4 修改选中节点
如下槽函数,其核心功能是修改
QTreeWidget
中当前选中节点的文本和图标,并在
QPlainTextEdit
中添加一行文本记录。
以下是概述:
这段代码的作用是在点击按钮时,修改
QTreeWidget
中当前选中节点的文本和图标,同时在
QPlainTextEdit
中记录这一修改操作。
void MainWindow::on_pushButton_modifynode_clicked() |
修改节点的执行效果如下图,当点击修改选中节点后则将自动替换节点名和图标信息。
1.5 删除选中节点
如下槽函数,其核心功能是删除
QTreeWidget
中当前选中节点,并在
QPlainTextEdit
中添加一行文本记录。
以下是概述:
这段代码的作用是在点击按钮时,删除
QTreeWidget
中当前选中的节点,并记录这一删除操作到
QPlainTextEdit
中。
void MainWindow::on_pushButton_delnode_clicked() |
删除节点有两种情况,如果只有父节点那么可以直接删除,如果有子节点则那就要一并删除,如下图;
1.6 枚举全部节点
如下槽函数,其核心功能是遍历
QTreeWidget
中的所有节点,并输出每个节点的文本。
以下是概述:
这段代码的作用是在点击按钮时,遍历
QTreeWidget
中的所有节点,输出每个节点的文本信息,并将信息记录到
QPlainTextEdit
中。
void MainWindow::on_pushButton_enumnode_clicked() |
枚举所有节点会将父节点与子节点一并输出,如下图;
1.7 枚举选中节点
如下槽函数,其核心功能是遍历
QTreeWidget
中的所有节点,并输出每个选中节点的文本信息。
以下是概述:
这段代码的作用是在点击按钮时,遍历
QTreeWidget
中的所有节点,输出每个被选中节点的文本信息,并将信息记录到
QPlainTextEdit
中。
void MainWindow::on_pushButton_enumselectnode_clicked() |
枚举所有选中的节点,此处需要打上对勾才会生效,如下图;
1.8 获取节点父节点
如下槽函数,其核心功能是获取当前选中节点的父节点(如果存在),输出父节点的序号和名字,并将信息记录到
QPlainTextEdit
中。
以下是概述:
这段代码的作用是在点击按钮时,获取当前选中节点的父节点(如果存在),输出父节点在顶级节点中的序号和名字,并将信息记录到
QPlainTextEdit
中。
void MainWindow::on_pushButton_getnode_clicked() |
当用户选中一个子节点时,可通过该槽函数获取其父节点的ID编号,如下图;
1.9 绑定右键菜单
首先我们在
MainWindow
主窗体中只保留一个
treeWidget
组件,接着直接来到
MainWindow
构造函数上,在该函数中我们通过动态创建一个
menuBar()
并将其隐藏起来,接着将菜单属性与
treeWidget
中的事件相互绑定,最后初始化填充一些测试数据,其代码如下;
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) |
此时,当
treeWidget
中的右键被点击后则将触发
on_treeWidget_customContextMenuRequested
槽函数,此函数中动态的新建一个菜单,并在鼠标点击位置将其显示输出,代码如下;
// 当treeWidget中的右键被点击时则触发 |
运行后读者可看到如下图所示的输出效果;