【QT】QTreeWidget控件的使用

2023-12-18 16:52:25

目录

1.概述

2.QTreeWidget控件功能接口

2.1 构造函数

2.2?添加和访问顶级条目

2.3?条目访问函数

2.4?当前条目的操作

2.5?条目查找和排序

2.6?条目显示和运行时条目编辑

2.7?信号

2.8?槽函数

2.9?基类 QTreeView 的函数

2.10?树头条目

2.11选中行为和选中模式

3.QTreeWidget控件功能实例介绍

3.1 本实例的目录树节点操作规则

3.2目录树初始化添加顶层节点

3.3添加目录节点

3.4 添加图片文件节点

3.5 当前节点变化后的响应

3.6 删除节点

3.7 节点的遍历

1.概述

???QTreeWidget类是创建和管理目录结构的类,它继承自QTreeView,可以显示多列数据和树形结构的层次关系,还提供了许多交互功能。可以支持单选、多选和可编辑的节点,还可以自定义节点的样式和布局。除此之外,QTreeWidget 还支持信号和槽机制,可以方便地处理节点的操作事件,如点击、双击、选择等等。

2.QTreeWidget控件功能接口

2.1 构造函数

QTreeWidget(QWidget * parent = 0)
参数里只有指定父窗口或父控件的指针 parent 。树形控件在添加条目之前,必须要先设置列数:
void setColumnCount(int columns) //设置列数
int columnCount() const //获取列数

2.2?添加和访问顶级条目

树形控件顶级条目的操作比较类似 QListWidget 的列表条目操作函数。新建条目之后,可以用如下函数把条目添加到树形控件的顶级条目列表末尾:
void QTreeWidget::addTopLevelItem(QTreeWidgetItem * item) //添加一个顶级条目到末尾
void QTreeWidget::addTopLevelItems(const QList<QTreeWidgetItem *> & items) //添加多个顶级条目到末尾
如果希望将条目插入到指定顶级条目列表的 index 序号位置,使用如下函数:
void QTreeWidget::insertTopLevelItem(int index, QTreeWidgetItem * item)
void QTreeWidget::insertTopLevelItems(int index, const QList<QTreeWidgetItem *> & items)
树形控件所有的顶级条目父节点指针都为 NULL (父节点是指树形层次中的节点关系,而条目的父控件依然是树形控件本身)。
添加了顶级条目之后,可以对顶级条目进行计数:
int QTreeWidget::topLevelItemCount() const

2.3?条目访问函数

对于顶级条目,如果知道顶级条目的序号获取对应的条目:
QTreeWidgetItem * QTreeWidget::topLevelItem(int index) const
反过来,对于已知顶级条目对象,查看其顶级序号:如果条目不是顶级条目或者条目不属于该控件,那么会返回 -1。
int QTreeWidget::indexOfTopLevelItem(QTreeWidgetItem * item) const
树形控件实际运行时,可能既有顶级条目,也有展开后的子孙条目同时显示,所以某个条目上面或下面的相邻条目不一定是同级别的兄弟条目,有可能是叔辈祖 辈的条目,也 可能是子辈孙辈条目。获取某个条目的相邻条目函数为:
QTreeWidgetItem * QTreeWidget::itemAbove(const QTreeWidgetItem * item) const //上面相邻条目
QTreeWidgetItem * QTreeWidget::itemBelow(const QTreeWidgetItem * item) const //下面相邻条目
从屏幕控件显示角度,如果根据树形控件 内部相对坐标 获取条目(树形控件显示区域的左上角为原点),使用下面函数:
QTreeWidgetItem * QTreeWidget::itemAt(const QPoint & p) const//用 QPoint 对象表示相对坐标
QTreeWidgetItem * QTreeWidget::itemAt(int x, int y) const//直接用 x 和 y 数值表示坐标
//如果对应坐标没有条目,会返回 NULL,注意判断 返回值。
树形控件也是自带滚动条的,如果条目特别多,自动显示滚动条,对于树形控件在屏幕可见的条目,可以根据条目对象获取它的 可视矩形 (树形控件显示区域的 左上角为原 点):
QRect QTreeWidget::visualItemRect(const QTreeWidgetItem * item) const

2.4?当前条目的操作

树形控件的选中操作默认比较像 QListWidget,如果不手动设置,只能选中一个高亮条目。
获取当前高亮选中条目的函数为:
QTreeWidgetItem * QTreeWidget::currentItem() const
树形控件可以有多列,当前条目被点击选中的列号为:
int QTreeWidget::currentColumn() const
树形控件内的条目一般都没有固定行号, 因为条目可以展开也可以折叠,行号是变化的,所以没有基于行号的操作函数。
如果要设置某个条目为当前选中的状态:
void QTreeWidget::setCurrentItem(QTreeWidgetItem * item)//设置该条目整行高亮选中
void QTreeWidget::setCurrentItem(QTreeWidgetItem * item, int column)//设置该条目行的 column 列高亮选中
void QTreeWidget::setCurrentItem(QTreeWidgetItem * item, int column, QItemSelectionModel::SelectionFlags command)//单次选中命令
如果当前高亮选中的状态发生变化,会触发如下信号:
//注意指针可能是 NULL,使用指针前一定要判断指针非空。
void QTreeWidget::currentItemChanged(QTreeWidgetItem * current, QTreeWidgetItem * previous)//参数里分别是当前高亮选中的条目,和之前高亮选中的条目

2.5?条目查找和排序

如果要根据模板子串查找某列文本匹配的条目,使用如下函数:
//该函数只查找一列的文本,其他列的文本是不查找的。如果需要查找所有列数据,那么要根据不同列号逐列查询。
QList<QTreeWidgetItem *> QTreeWidget::findItems(const QString & text, Qt::MatchFlags flags, int column = 0) const //参数里text是模板子串,flags是匹配标志,第三个参数是指定查找的列。
类似表格控件,树形控件也可以按照列的文本进行自动排序,自动排序的设置函数为:
bool????isSortingEnabled() const??????????//设置是否自动排序
void????setSortingEnabled(bool enable)???//查看是否开启自动排序
指定排序的列号和升序降序,使用从基类继承的函数:
//在没有开启自动排序的情况下,也可以调用该函数进行一次性的条目排序。
void QTreeView::sortByColumn(int column, Qt::SortOrder order)

2.6?条目显示和运行时条目编辑

可以为条目的某列“单元格”设置单独的控件来静态显示(控件不具有编辑功能):
void QTreeWidget::setItemWidget(QTreeWidgetItem * item, int column, QWidget * widget) //设置条目列控件
QWidget * QTreeWidget::itemWidget(QTreeWidgetItem * item, int column) const //获取条目列控件,不设置就是NULL
  • 注意:该函数只能在条目添加到树形控件之后才能调用,否则无效,并且条目列控件只能用于显示,无法编辑。
  • itemWidget 条目控件,在默认情况下是与条目本身数据完全无关的,是条目数据的替换品,而不是协作模式。只有手动设置信号与槽,它们才可能关联上。
  • QListWidget 和 QTreeWidget 的条目控件都是静态显示,不能编辑。
  • QTreeWidget 控件的条目列控件 widget 还必须把 autoFillBackground 属性设置为 true,如果不是自动填充背景,那么默认是透明背景,这样控件的内容和内部模型数据(就是条目的列数据)同时显示,文本会重影。
删除条目的列控件使用如下函数:
void QTreeWidget::removeItemWidget(QTreeWidgetItem * item, int column)//这个函数没有返回值,会自动地彻底删除条目列控件。
在大多数情况下都用不到 itemWidget ,因为能够为条目设置可编辑标志位,然后调用如下函数开启树形控件自带的文本编辑器:
void QTreeWidget::editItem(QTreeWidgetItem * item, int column = 0)//参数 item 是指定的条目,column 是条目的列(类似“单元格”)。
在没有为条目设置可编辑标志位的情况下,可以调用下面一对函数进行持续编辑器的开启和关闭:
注意这对函数一开一关,要成对调用,否则编辑完了不会自动关闭持续编辑器。
void QTreeWidget::openPersistentEditor(QTreeWidgetItem * item, int column = 0)
void QTreeWidget::closePersistentEditor(QTreeWidgetItem * item, int column = 0)

2.7?信号

常规信号:
void itemActivated(QTreeWidgetItem * item, int column) //条目列被激活
void itemChanged(QTreeWidgetItem * item, int column)???//条目列的数据发生变化,比如文本或图标修改了
void itemClicked(QTreeWidgetItem * item, int column)??//条目列被单击
void itemDoubleClicked(QTreeWidgetItem * item, int column) //条目列被双击
void itemEntered(QTreeWidgetItem * item, int column) //进入条目列
void itemPressed(QTreeWidgetItem * item, int column) //条目列被点 击按下
树形控件展开和折叠信号:
如果调用槽函数? expandAll() 展开所有子孙条目,那么不会触发 itemExpanded() 信号,因为触发太多会非常影响性能。 类似地,如果用槽函数 collapseAll() 折叠所有子孙条目,也不会触发 itemCollapsed() 信号,以免影响性能。
void QTreeWidget::itemExpanded(QTreeWidgetItem * item)??//条目展开时发送信号
void QTreeWidget::itemCollapsed(QTreeWidgetItem * item) //条目折叠时发送信号

2.8?槽函数

树形控件的槽函数包括四个:
void clear() //清空整个树形控件
void collapseItem(const QTreeWidgetItem * item) //折叠指定的条目
void expandItem(const QTreeWidgetItem * item)??//展开指定 条目
void scrollToItem(const QTreeWidgetItem * item, QAbstractItemView::ScrollHint hint = EnsureVisible) //滚动到指定条目,第二个参数是滚到到该条目的显示方式

2.9?基类 QTreeView 的函数

QTreeView 的功能函数也很多,这里列举几个可能常用的,关于列隐藏或显示、设置列宽的函数如下:
void QTreeView::setColumnHidden(int column, bool hide) //设置列隐藏或显示
bool QTreeView::isColumnHidden(int column) const //判断列是否隐藏
void QTreeView::hideColumn(int column) //槽函数,隐藏指定列
void QTreeView::showColumn(int column) //槽函数,显示指定列
void QTreeView::setColumnWidth(int column, int width) //设置列宽
int QTreeView::columnWidth(int column) const //获取指定列的宽度
void QTreeView::resizeColumnToContents(int column) //槽函数,自动调整 指定列的宽度
属性 indentation 控制显示父子节点的缩进宽度:
int indentation() const????//获取父子节点的缩进宽度
void setIndentation(int i) //设置缩进宽度
void resetIndentation()????//重置缩进宽度为默认值
基类还有几个常用的折叠和展开槽函数:
void collapseAll() //折叠所有子孙节点,这样只能看到顶级节点
void expandAll() //展开所有子孙节点,完全展开的树
/*
*expandToDepth() 函数是指一直展开,直到将第 depth 层级的子节点都展开为止。以顶级条目为第 0 层级,顶级条目的直接子节点为第 1 层级,孙子节点为第 2 层级,依次类推。
*如果把 expandToDepth() 参数设置成负数,那么相当于展开无穷大级别,就是展开所有的子孙节点。
*/
void expandToDepth(int depth) //展开 depth 层级的子节点

2.10?树头条目

树形控件只有一个表头,就是显示在上面的水平表头,也叫树头条目。设置树头条目的函数为:
//无论是 QTableWidget 还是 QTreeWidget 的表头,都是 QHeaderView 子控件显示。
void QTreeWidget::setHeaderItem(QTreeWidgetItem * item) //设置树头条目,树头条目可以有多列数据,相当于多列的表头一次性设置了。
void QTreeWidget::setHeaderLabel(const QString & label) //只设置第 0 列的表头
void QTreeWidget::setHeaderLabels(const QStringList & labels) //设置多列的表头
QTreeWidgetItem * QTreeWidget::headerItem() const //获取树头条目
树头条目本质其实也是由 QHeaderView 子控件来显示的,可以在基类找到相关函数:
QHeaderView * QTreeView::header() const //获取表头视图控件
void QTreeView::setHeader(QHeaderView * header) //设置表头视图, 一般树形控件不需要用这个函数
void QTreeView::setHeaderHidden(bool hide) //设置表头是否隐藏
bool QTreeView::isHeaderHidden() const //判断是否隐藏了表头

2.11选中行为和选中模式

与 QTableWidget 类似,QTreeWidget也从祖类 QAbstractItemView 继承了选中行为和选中模式的属性:
QAbstractItemView::SelectionBehavior??selectionBehavior() const //获取选中行为,按条目选中、整行或整列选中
void setSelectionBehavior(QAbstractItemView::SelectionBehavior behavior) //设置选中行为
QAbstractItemView::SelectionMode??selectionMode() const //获取选中模式,比如单选、多选、扩展选择
void setSelectionMode(QAbstractItemView::SelectionMode mode) //设置选中模式
默认情况下,树形控件是按照整行选中,并且是单选模式,如果把选中模式改成多选的 QAbstractItemView::ExtendedSelection,那么树形控件也可以使多选的,这时候信号 itemSelectionChanged() 就能派上用场:
void QTreeWidget::itemSelectionChanged()
多选状态变化时会触发该信号(单选模式也触发,只是不需要用这个信号),可以关联该信号,监视当前所有选中的条目:
QList<QTreeWidgetItem *> QTreeWidget::selectedItems() const
????????注意,这里的选中条目仅仅是指实际显示的直接选中的条目,不包括折叠隐藏的子孙条目计数,因为选中父节点与选中其子孙节点没关系,不会递归选中所有子孙。
????????树形控件及其基类没有递归选中子条目的属性或函数,如果希望递归选中某个节点的所有子孙节点,那么需要自行编写递归函数。

3.QTreeWidget控件功能实例介绍

3.1 本实例的目录树节点操作规则

本实例的目录树节点操作定义如下一些规则。
  • 将目录树的节点分为3种类型,顶层节点、分组节点和图片节点。
  • 窗口创建时初始化目录树,它只有一个顶层节点,这个顶层节点不能被删除,而且不允许
  • 再新建顶层节点。
  • 顶层节点下允许添加分组节点和图片节点。
  • 分组节点下可以添加分组节点和图片节点,分组节点的级数无限制。
  • 图片节点是终端节点,可以在图片节点同级再添加图片节点。
  • 每个节点创建时设置其类型信息,图片节点存储其完整文件名作为自定义数据。
  • 单击一个图片文件节点时,显示其关联文件的图片。
为便于后面说明代码的实现,将主窗口类MainWindow中增加的自定义内容先列出来,代码
如下。这些枚举类型、变量和函数的功能在后面再具体介绍。
?
class MainWindow : public QMainWindow
{
????Q_OBJECT
private:
//枚举类型treeItemType, 用于创建 QTreeWidgetItem 时作为节点的type, 自定义类型必须大于1000
//itTopItem 顶层节点;??itGroupItem 组节点; itImageItem 图片
????enum????treeItemType{itTopItem=1001,itGroupItem,itImageItem};
//枚举类型,表示列号
????enum????treeColNum{colItem=0, colItemType=1}; //目录树列的编号定义
????QLabel??*LabFileName;
????QPixmap curPixmap; //当前的图片
????float???pixRatio;//当前图片缩放比例
????void????iniTree();//目录树初始化
????void????addFolderItem(QTreeWidgetItem *parItem, QString dirName);//添加一个目录节点
????QString getFinalFolderName(const QString &fullPathName);//从目录全名称中获取最后的文件夹名称
????void????addImageItem(QTreeWidgetItem *parItem,QString aFilename);//添加一个图片节点
????void????displayImage(QTreeWidgetItem *item); //显示一个图片节点的图片
????void????changeItemCaption(QTreeWidgetItem *item); //遍历改变节点标题
};

3.2目录树初始化添加顶层节点

主窗口MainWindow的构造函数会调用自定义函数iniTree(),对目录树进行初始化,窗口构 造函数和iniTree()代码如下
MainWindow::MainWindow(QWidget *parent) :
????QMainWindow(parent),
????ui(new Ui::MainWindow)
{
????ui->setupUi(this);
????LabFileName=new QLabel("");
????ui->statusBar->addWidget(LabFileName);
????this->setCentralWidget(ui->scrollArea); //设置中心布局组件
????iniTree();//初始化目录树
}

void MainWindow::iniTree()
{ //初始化Tree
? ? QString????dataStr=""; // Item的Data 存储的string
????ui->treeFiles->clear();//清除目录树所有节点
????QIcon???icon;
????icon.addFile(":/images/icons/15.ico"); //设置ICON的图标
????QTreeWidgetItem*??item=new QTreeWidgetItem(MainWindow::itTopItem); //新建节点时设定类型为 itTopItem
????item->setIcon(MainWindow::colItem,icon); //设置第1列的图标
????item->setText(MainWindow::colItem,"图片文件"); //设置第1列的文字
????item->setText(MainWindow::colItemType,"type=itTopItem");??//设置第2列的文字
????item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsAutoTristate);
????item->setCheckState(colItem,Qt::Checked);//设置为选中
????item->setData(MainWindow::colItem,Qt::UserRole,QVariant(dataStr)); //设置节点第1列的Qt::UserRole的Data
????ui->treeFiles->addTopLevelItem(item);//添加顶层节点
}
  • QTreeWidget的每个节点都是一个QTreeWidgetItem对象,添加一个节点前需先创建它,并做 好相关设置。
  • ?? ?创建节点的语句是:
?? ?item->newQTreeWidgetItem(MainWindow::itTopItem);
  • 传递了一个枚举常量MainWindow::itTopItem作为构造函数的参数,表示节点的类型。在构造 函数里传递一个类型值之后,就可以用QTreeWidgetItem::type()返回这个节点的类型值。
  • itTopItem是在MainWindow里定义的枚举类型treeltemType的一个常量值。枚举类型 treeltemType定义了节点的类型,自定义的节点类型值必须大于1000。
  • QTreeWidgetItem的setlcon()和setText()都需要传递一个列号作为参数,指定对哪个列进行设
置。列号可以直接用数字,但是为了便于理解代码和统一修改,在MainWindow里定义了枚举类 型treeColNum,colltem表示第1列,colItemType表示第2列。
  • setFlags()函数设置节点的一些属性标记,是Qt::ItemFlag枚举类型常量的组合。
  • setData()函数为节点的某一列设置一个角色数据,setData()函数原型为:
?? ?? ?void QTreeWidgetItem::setData(int column,int role,const QVariant &value)
?? ??? ?其中,column是列号,role是角色的值,value是一个QVariant类型的数。
  • 代码中设置节点数据的语句是:
?? ??? ?item->setData(MainWindow::colltem,Qt::UserRole,QVariant(dataStr));
?? ??? ?它为节点的第1列,角色Qt::UserRole,设置了一个字符串数据datastr。Qt::UserRole是枚举
类型Qt::ItemDataRole中一个预定义的值。
?? ??? ?创建并设置好节点后,用QTreeWidget::addTopLevelItem()函数将节点作为顶层节点添加到目
录树。

3.3添加目录节点

actAddFolder是用于添加组节点的Action,当目录树上的当前节点类型是itTopItem或 itGroupItem 类型时,才可以添加组节点。 actAddFolder 的 triggered() 信号的槽函数,以及相关自定
义函数的代码如下:
void MainWindow::on_actAddFolder_triggered()
{// 选择一个文件夹,作为当前节点的子节点加入
??QString dir=QFileDialog::getExistingDirectory();//选择目录
??if (!dir.isEmpty()) //选择目录名称不为空
??{
??????QTreeWidgetItem* parItem=ui->treeFiles->currentItem(); //当前节点
??????addFolderItem(parItem,dir);//在父节点下面添加一个组节点
??}
}

void MainWindow::addFolderItem(QTreeWidgetItem *parItem, QString dirName)
{//添加一个目录节点
????QIcon???icon(":/images/icons/open3.bmp");
????QString NodeText=getFinalFolderName(dirName); //从一个完整目录名称里,获得最后的文件夹名称
????QTreeWidgetItem *item; //节点
????item=new QTreeWidgetItem(MainWindow::itGroupItem); //新建节点, 设定type为 itGroupItem
????item->setIcon(colItem,icon); //设置图标
????item->setText(colItem,NodeText); //最后的文件夹名称,第1列
????item->setText(colItemType,"type=itGroupItem"); //完整目录名称,第2列
????item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsAutoTristate); //设置节点选项
????item->setCheckState(colItem,Qt::Checked); //节点选中
????item->setData(colItem,Qt::UserRole,QVariant(dirName)); //设置角色为Qt::UserRole的Data,存储完整目录名称
????parItem->addChild(item); //在父节点下面添加子节点
}

QString MainWindow::getFinalFolderName(const QString &fullPathName)
{//从一个完整目录名称里,获得最后的文件夹名称
????int cnt=fullPathName.length(); //字符串长度
????int i=fullPathName.lastIndexOf("/");//??最后一次出现的位置
????QString str=fullPathName.right(cnt-i-1); //获得最后的文件夹的名称
????return str;
}
actAddFolder的槽函数首先用文件对话框获取一个目录名称,再获取目录树的当前节点,然
后调用自定义函数addFolderItem()添加一个组节点,新添加的节点将会作为当前节点的子节点。
addFolderltem()函数根据传递来的父节点parltem和目录全称dirName,创建并添加节点。首
先用自定义函数getFinalFolderName()获取目录全称的最后一级的文件夹名称,这个文件夹名称将
作为新建节点的标题:然后创建一个节点,创建时设置其节点类型为itGroupItem,表示分组节点,
再设置属性和关联数据,关联数据就是目录的全路径字符串:最后调用QTreeWidgetItem::addChild() 函数,将创建的节点作为父节点的一个子节点添加到目录树。

3.4 添加图片文件节点

actAddFiles是添加图片文件节点的Action,目录树的当前节点为任何类型时这个Action都可
用。actAddFiles的槽函数,以及相关自定义函数的代码如下:
void MainWindow::on_actAddFiles_triggered()
{//添加图片文件节点
????QStringList files=QFileDialog::getOpenFileNames(this,"选择一个或多个文件","","Images(*.jpg)");//多选文件
????if (files.isEmpty()) //如果一个文件都没选
????????return;
????QTreeWidgetItem *parItem,*item; //节点
????item=ui->treeFiles->currentItem(); //当前节点
????if (item->type()==itImageItem) //若当前节点是图片节点,取其父节点作为父节点
???????parItem=item->parent();
????else //否则取当前节点为父节点
???????parItem=item;
????for (int i = 0; i < files.size(); ++i)
????{
????????QString aFilename=files.at(i); //得到StringList里的一行,也就是一个文件名
????????addImageItem(parItem,aFilename); //添加一个图片节点
????}
}


void MainWindow::addImageItem(QTreeWidgetItem *parItem, QString aFilename)
{//添加一个图片文件节点
????QIcon???icon(":/images/icons/31.ico");//ICON的图标
????QString NodeText=getFinalFolderName(aFilename); //获得最后的文件名称
????QTreeWidgetItem *item; //节点
????item=new QTreeWidgetItem(MainWindow::itImageItem); //新建节点时设定类型为 itImageItem
????item->setIcon(colItem,icon); //设置图标
????item->setText(colItem,NodeText); //最后的文件夹名称
????item->setText(colItemType,"type=itImageItem"); //完整目录名称
????item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsAutoTristate); //设置节点选项
????item->setCheckState(colItem,Qt::Checked); //节点选中
????item->setData(colItem,Qt::UserRole,QVariant(aFilename)); //设置节点Qt::UserRole的Data,存储完整文件名称
????parItem->addChild(item); //在父节点下面添加子节点
}
?? ?actAddFiles的槽函数首先用QFileDialog::getOpenFileNames(),获取图片文件列表,通过
QTreeWidget::currentltem()函数获得目录树的当前节点item。
?? ?item->type()将返回节点的类型,也就是创建节点时传递给构造函数的那个参数。如果当前节
点类型是图片节点(itlmageltem),就使用当前节点的父节点,作为将要添加的图片节点的父节点,
否则就用当前节点作为父节点。
?? ?然后遍历所选图片文件列表,调用自定义函数addlmageltem()逐一添加图片节点到父节点下。
?? ?addlmageltem()根据图片文件名称,创建一个节点并添加到父节点下面,在使用setData()设置
节点数据时,将图片带路径的文件名aFilename作为节点的数据,这个数据在单击节点打开图片时
会用到。

3.5 当前节点变化后的响应

目录树上当前节点变化时,会发射currentltemChanged()信号,为此信号创建槽函数,实现当
前节点类型判断、几个Action的使能控制、显示图片等功能,代码如下:
void MainWindow::on_treeFiles_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{ //当前节点选择变化时触发
????Q_UNUSED(previous);
????if??(current==NULL)
????????return;
????int var=current->type();//节点的类型
????switch(var)
????{
????????case??itTopItem: //顶层节点
??????????ui->actAddFolder->setEnabled(true);
??????????ui->actAddFiles->setEnabled(true);
??????????ui->actDeleteItem->setEnabled(false);????//顶层节点不能删除
??????????break;
????????case??itGroupItem: //文件组节点
??????????ui->actAddFolder->setEnabled(true);
??????????ui->actAddFiles->setEnabled(true);
??????????ui->actDeleteItem->setEnabled(true);
??????????break;

????????case??itImageItem: //图片文件节点
??????????ui->actAddFolder->setEnabled(false); //图片节点下不能添加目录节点
??????????ui->actAddFiles->setEnabled(true);
??????????ui->actDeleteItem->setEnabled(true);
??????????displayImage(current); //显示图片
??????????break;
????}
}
?? ?current是变化后的当前节点,通过current->type()获得当前节点的类型,根据节点类型控制界
面上3个Action的使能状态。如果是图片文件节点,还调用displaylmage0函数显示节点关联的
图片。
?? ?displaylmage()函数的功能实现在后面介绍QLabe1图片显示的部分会详细说明。

3.6 删除节点

除了顶层节点之外,选中一个节点后也可以删除它。actDeleteItem实现节点删除,其代码如下:
void MainWindow::on_actDeleteItem_triggered()
{//删除节点
//????QTreeWidgetItem *item,*parItem;
????QTreeWidgetItem* item =ui->treeFiles->currentItem(); //当前节点
????QTreeWidgetItem* parItem=item->parent(); //父节点
????parItem->removeChild(item);//The removed item will not be deleted
????delete item;
}
?? ?一个节点不能移除自己,所以需要获取其父节点,使用父节点的removeChild()函数来移除自
己。removeChild()移除一个节点,但是不从内存中删除它,所以还需调用delete。
?? ?若要删除顶层节点,则使用QTreeWidget::takeTopLevelItem(intindex)函数。

3.7 节点的遍历

?? ?目录树的节点都是QTreeWidget1tem类,可以嵌套多层。有时需要在目录树中遍历所有节点,
比如按条件查找某些节点、统一修改节点的标题等。遍历节点需要用到QTreeWidgetItem类的一
些关键函数,还需要设计嵌套函数。
?? ?actscanltems实现工具栏上“遍历节点”的功能,其槽函数及相关自定义函数代码如下:
void MainWindow::on_actScanItems_triggered()
{//遍历节点
????for (int i=0;i<ui->treeFiles->topLevelItemCount();i++)
????{
????????QTreeWidgetItem *item=ui->treeFiles->topLevelItem(i); //顶层节点
????????changeItemCaption(item); //更改节点标题
????}
}

void MainWindow::changeItemCaption(QTreeWidgetItem *item)
{ //改变节点的标题文字
????QString str="*"+item->text(colItem);??//节点标题前加“*”
????item->setText(colItem,str); //设置节点标题
????if (item->childCount()>0) //如果有子节点
????for (int i=0;i<item->childCount();i++) //遍历子节点
???????changeItemCaption(item->child(i));??//调用自己,可重入的函数
}
QTreeWidget组件的顶层节点没有父节点,要访问所有顶层节点,用到两个函数。
  • inttopLevelItemCount():返回顶层节点个数。
  • QTreeWidgetItem*topLevelItem(intindex):返回序号为index的顶层节点。
?? ?on_actscanltems_triggered()函数的for循环访问所有顶层节点,获取一个顶层节点item之后,
调用changeltemcaption(item)改变这个节点及其所有子节点的标题。
?? ?changeltemCaption(QTreeWidgetItem *item)是一个嵌套调用函数,即在这个函数里还会调用它自己。它的前两行更改传递来的节点item的标题,即在标题前加星号。后面的代码根据 item->childCount()是否大于0,判断这个节点是否有子节点,如果有子节点,则在后面的for循环里, 逐一获取,并作为参数调用changeltemcaption()函数。

文章来源:https://blog.csdn.net/u011671745/article/details/135064215
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。