Qt --- QTreeWidget 树形控件实例&遇到的问题

说明

  • 环境
    Qt软件版本 : 5.9.9
    实例参考书籍 : Qt5开发及实例 陆文周
    系统 : Win10 专业版

  • QTreeWidget 树形控件实例
    选中树形控件的父节点 或者 取消树形控件的父节点 子节点跟随父节点状态;
    子节点单独选中, 父节点在半选中状态;

代码

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

#include <QTreeWidgetItem>     

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void init();
    void updateParentItem(QTreeWidgetItem* item);

public slots:
    void treeItemChanged(QTreeWidgetItem* item, int column);

private:
    Ui::Widget *ui;

};
#endif // WIDGET_H

widget.c

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    init();
    /* itemChanged() 当指定项中列的内容发生更改时,会发出此信号 */
    connect(ui->treeWidget, SIGNAL(itemChanged(QTreeWidgetItem* , int)), this , SLOT(treeItemChanged(QTreeWidgetItem* , int)) );
}

Widget::~Widget()
{
    delete ui;
}

void Widget::init()
{
    ui->treeWidget->clear(); //* clear() 清除树内部的所有项选择

    ui->treeWidget->setHeaderHidden(true); //* 设置隐藏treeWidget表头显示

    //第一个分组
    QTreeWidgetItem *group1 = new QTreeWidgetItem(ui->treeWidget);
    group1->setText(0,"group1");
    group1->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
    group1->setCheckState(0,Qt::Unchecked);

    QTreeWidgetItem *subItem11 = new QTreeWidgetItem(group1);
    subItem11->setText(0,"subItem11");
    subItem11->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
    subItem11->setCheckState(0,Qt::Unchecked);

    QTreeWidgetItem *subItem12 = new QTreeWidgetItem(group1);
    subItem12->setText(0,"subItem12");
    subItem12->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
    subItem12->setCheckState(0,Qt::Unchecked);

    QTreeWidgetItem *subItem13 = new QTreeWidgetItem(group1);
    subItem13->setText(0,"subItem13");
    subItem13->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
    subItem13->setCheckState(0,Qt::Unchecked);

    QTreeWidgetItem *subItem14 = new QTreeWidgetItem(group1);
    subItem14->setText(0,"subItem14");
    subItem14->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
    subItem14->setCheckState(0,Qt::Unchecked);

    //第二个分组
    QTreeWidgetItem *group2 = new QTreeWidgetItem(ui->treeWidget);
    group2->setText(0,"group2");
    group2->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
    group2->setCheckState(0,Qt::Unchecked);

    QTreeWidgetItem *subItem21 = new QTreeWidgetItem(group2);
    subItem21->setText(0,"subItem21");
    subItem21->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
    subItem21->setCheckState(0,Qt::Unchecked);

    QTreeWidgetItem *subItem22 = new QTreeWidgetItem(group2);
    subItem22->setText(0,"subItem22");
    subItem22->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
    subItem22->setCheckState(0,Qt::Unchecked);

    QTreeWidgetItem *subItem23 = new QTreeWidgetItem(group2);
    subItem23->setText(0,"subItem23");
    subItem23->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
    subItem23->setCheckState(0,Qt::Unchecked);
}

void Widget::updateParentItem(QTreeWidgetItem* item) //* 判断并设置父节点的状态
{
    QTreeWidgetItem *parent = item ->parent(); //* parent() 返回项目的父级
    if(parent == NULL)
    {
        return;
    }
    /* 统计选中的子节点的个数 */
    int selectedCount = 0;
    int childCount = parent->childCount();  //* childCount() 返回子项目的数量

    for (int i = 0; i < childCount; i++)
    {
        QTreeWidgetItem *childItem =  parent->child(i);
        if(childItem->checkState(0) == Qt::Checked)
        {
            selectedCount++;
        }
    }
   /* 根据选中的子节点的个数 更新父节点的状态 */
    if(selectedCount <= 0)
    {
        parent->setCheckState(0, Qt::Unchecked);
    }
    else if(selectedCount > 0 && selectedCount < childCount)
    {
        //部分选中状态
        parent->setCheckState(0, Qt::PartiallyChecked);
    }
    else if(selectedCount == childCount)
    {
        //未选中状态
        parent->setCheckState(0, Qt::Checked);
    }
}

void Widget::treeItemChanged(QTreeWidgetItem* item, int column)
{
    QString itemText = item ->text(0);
    //选中时
    if(Qt::Checked == item ->checkState(0))
    {
        QTreeWidgetItem* parent = item ->parent();
        int count = item ->childCount(); // 获取子部件数目
        if(count > 0) //判断是否有子节点
        {
            for (int i = 0; i < count; i++)
            {
                //子节点也选中 有的话将下面子节点全部选中
                item ->child(i) ->setCheckState(0, Qt::Checked);
            }
        }
        else
        {
            //是子节点
            updateParentItem(item);
        }
    }
    else if(Qt::Unchecked == item->checkState(0))
    {
        int count = item ->childCount();
        if(count > 0)
        {
            for (int i = 0; i < count; i++)
            {
                item ->child(i) ->setCheckState(0, Qt::Unchecked);
            }
        }
        else
        {
            updateParentItem(item);
        }
    }
}

源码下载

https://download.csdn.net/download/occasionally/87389132

遇到的问题

在使用Qt treeWidget 控件时发现总会出现表头显示1(如图片), 在ui中删除无效, 发现可以通过下列方式解决。
请添加图片描述

解决方式1

设计界面 选中UI组件treeWidget直接设置 HeaderHidden属性
请添加图片描述

解决方式2

  1. 程序中使用 setHeaderHidden() 设置; 在界面构造函数中添加下面语句;
    ui->treeWidget->setHeaderHidden(true);

操作后的显示

请添加图片描述

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt是一个跨平台的C++应用程序开发框架,提供了丰富的控件和功能,可以用于开发各种类型的应用程序。 在实现表格树控件时,如果需要支持多级表头,可以借助Qt的QHeaderView类来实现。QHeaderView类是Qt中用于表格或树型视图的表头控件,它可以显示列或行的标题,并且支持拖动和调整列宽度。 首先,创建一个QTreeView控件作为表格树控件的显示部分。然后,创建一个QHeaderView对象作为表格树控件的表头,使用setModel()函数将表头设置给表格树控件。接下来,设置表头的显示模式为水平模式,使用setSectionResizeMode()函数设置每一列的调整方式,例如,可以设置为可以自动调整大小或者禁止调整大小。 为了支持多级表头,可以使用QHeaderView的addSection()函数来添加多级表头。逐级添加表头时,需要设置每一级表头的标签、起始列、列数和对齐方式。可以使用setHeaderData()函数为每一级的表头设置样式。 接着,使用setHeaderHidden()函数将QTreeView的默认表头隐藏起来,这样就只展示了我们自定义的多级表头。同时,可以使用setRootIsDecorated()函数将树节点的展开和收缩图标隐藏起来,以使得表格树控件更加美观。 最后,将数据模型设置给QTreeView控件,通过添加树节点和设置节点的父子关系,来组织表格树的数据结构。数据模型可以继承自QAbstractItemModel类,实现相关的接口函数,以提供数据的展示和操作。 通过以上步骤,我们就可以实现一个支持多级表头的表格树控件。用户可以通过拖动和调整表头以调整列宽度,同时展示复杂的表头结构,方便显示和操作大量数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值