QTreeWidget

QTreeWidget这个类是一个树形控件,要和QTreeWidgetItem一起使用,因为QTreeWidget是一个整体的控件,而QTreeWidgetItem是树的节点.
首先在widget中拖拽一个QTreeWidget控件.
然后定义init()函数用于初始化控件

void Widget::init()
{
    ui->treeWidget->clear();
    //第一个分组
    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->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEditable|Qt::ItemIsSelectable);
    subItem11->setText(0,"subItem1");
    subItem11->setCheckState(0,Qt::Unchecked);
    QTreeWidgetItem *subItem12=new QTreeWidgetItem(group1);
    subItem12->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
    subItem12->setText(0,"subItem2");
    subItem12->setCheckState(0,Qt::Unchecked);
    QTreeWidgetItem *subItem13=new QTreeWidgetItem(group1);
    subItem13->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
    subItem13->setText(0,"subItem3");
    subItem13->setCheckState(0,Qt::Unchecked);
    QTreeWidgetItem *subItem14=new QTreeWidgetItem(group1);
    subItem14->setFlage(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
    subItem14->setText(0,"subItem4");
    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->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
    subItem21->setText(0,"subItem2");
    subItem21->setCheckState(0,Qt::Unchecked);
    QTreeWidgetItem *subItem22=new QTreeWidgetItem(group2);
    subItem22->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
    subItem22->setText(0,"subItem22");
    subItem22->setCheckState(0,Qt::Unchecked);
    QTreeWidgetItem *subItem23=new QTreeWidgetItem(group2);
    subItem23->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
    subItem23->setText(0,"subItem23");
    subItem23->setCheckState(0,Qt::Unchecked);
}

树形控件的特征就是当选中顶层的树形节点时,子节点全部被选中,当取消顶层树形节点时,子节点全部被取消状态.
首先我们先来看一下节点类,节点类QTreeWidgetItem有很多构造函数,先来看其中的一个
QTreeWidgetItem(QTreeWidget *parent,const QStringList &strings,int type=Type);
注意第二个选项是QStringList而不是QString.
如果使用QString,则需要强制类型转换为QStringList
我们可以使用QTreeWidget的setHeaderLabels函数设置表头
例如

QTreeWidget treeWidget;

QStringList headers;
headers << "Name" << "Number";
treeWidget.setHeaderLabels(headers);

如果不想要表头,可以调用setHeaderHidden()将其隐藏.
这里写图片描述
group1->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable)
这里ItemIsUserCheckable如果没有这个选项,则树形框将不能选择,Qt::ItemIsEnabled 如果没有这个选项,树形框也将不能选择。Qt::ItemIsSelectable 这个不知道是干什么用的。

QTreeWidgetItem::setCheckState(int column,Qt::CheceState state)
设置这一列是否被选中
Qt::CheckState有三种状态
Qt::Unchecked
就是上边那种状态
Qt::Checked
这里写图片描述
Qt::PartiallyChecked
这里写图片描述

当节点状态改变时,使用节点改变信号itemChanged

connect(ui->treeWidget,SIGNAL(itemChanged(QTreeWidgetItem*,int)),this,SLOT(treeItemChanged(QTreeWidget*,int)));

然后编写treeItmeChanged(QTreeWidget*,int)槽函数。这个函数的作用是当树节点被选中时,子节点也全部被选中,当其中一个子节点被选中时,树节点会呈现部分被选中的状态。

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);
        }
    }

}

下面是如果选中的节点是子节点的处理

void Widget::updateParentItem(QTreeWidgetItem* item)
{
    QTreeWidgetItem *parent = item->parent();//返回这个节点的父节点
    if (parent == NULL)//如果没有父节点,返回
    {
         return;
    }

    //选中的子节点个数
    int selectedCount = 0;//计算选中的个数
    int childCount = parent->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);//如果选中的个数为0,则父节点也不选中
    }
    else if (selectedCount > 0 && selectedCount < childCount)//如果只选择了部分,则父节点的状态为部分选中
    {
         //部分选中状态
         parent->setCheckState(0, Qt::PartiallyChecked);
    }
    else if (selectedCount == childCount)//如果全部选中,则父节点的状态为全部选中。
    {
         //未选中状态
         parent->setCheckState(0, Qt::Checked);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值