【QT】QTreeWidget控件的使用

目录

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 & items) //添加多个顶级条目到末尾
如果希望将条目插入到指定顶级条目列表的 index 序号位置,使用如下函数:
void QTreeWidget::insertTopLevelItem(int index, QTreeWidgetItem * item)
void QTreeWidget::insertTopLevelItems(int index, const QList & 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 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 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;itreeFiles->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;ichildCount();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()函数。

你可能感兴趣的:(Qt,qt,开发语言)