Bootstrap

树控件QTreeWidget

树控件跟表格控件类似,也可以有多列,也可以只有1列,可以有多行,只不过每一行都是一个QTreeWidgetItem,每一行都是一个可以展开的树

常用属性和方法

显示和隐藏标题栏

树控件只有水平标题栏

//获取和设置标题栏的显隐
bool isHeaderHidden() const
void setHeaderHidden(bool hide)

//隐藏标题栏
tree->setHeaderHidden(true);

 还可以先获取到树控件的标题栏,然后调用标题栏的方法,来设置标题栏是否可见

//设置标题栏是否可见
void QHeaderView::setVisible(bool v)

//隐藏标题栏
tree->header()->setVisible(false);

点击标题栏排序

//获取和设置标题栏是否开启了排序
bool isSortingEnabled() const
void setSortingEnabled(bool enable)

//开启排序
tree->setSortingEnabled(true);

 开启点击标题栏会出现一个排序箭头,点击标题栏,就会根据当前列排序

动画效果

开启树控件里面的条目展开时会有一个缓冲效果,而不是立即展开

//获取和设置动画效果
bool isAnimated() const
void setAnimated(bool enable)


//开启动画效果
tree->setAnimated(true);

没开启:

开启了,条目的展开有一定的缓冲:

 滚动条的显示和隐藏

//设置和获取水平滚动条的显隐
Qt::ScrollBarPolicy horizontalScrollBarPolicy() const
void setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy)

//设置和获取垂直滚动条的显隐
Qt::ScrollBarPolicy verticalScrollBarPolicy() const
void setVerticalScrollBarPolicy(Qt::ScrollBarPolicy)


//隐藏水平和垂直滚动条
tree->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
tree->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

Qt::ScrollBarPolicy有三种取值:

  • Qt::ScrollBarAsNeeded,控件宽高太小导致内容显示不全时滚动条会出现
  • Qt::ScrollBarAlwaysOff,总是关闭
  • Qt::ScrollBarAlwaysOn,总是开启

开启:

选择模式

单选、多选、按住ctrl键多选,shift键多选...

//获取和设置控件的选择模式
QAbstractItemView::SelectionMode selectionMode() const
void setSelectionMode(QAbstractItemView::SelectionMode mode)


//设置为多选,既可以按shift也可以按ctrl键选择
tree->setSelectionMode(QAbstractItemView::ExtendedSelection);

 mode有5种取值:

  • QAbstractItemView::SingleSelection,只能但选
  • QAbstractItemView::ContiguousSelection,按住ctrl键可以多选
  • QAbstractItemView::ExtendedSelection,按住ctrl或者shift键可以多选
  • QAbstractItemView::MultiSelection,只要点击就能多选
  • QAbstractItemView::NoSelection,不能选择

按住ctrl或者shift键可以多选:

选择行为

选择时是选择单个条目、或者一整行 ,一整列

//获取和设置控件的选择行为
QAbstractItemView::SelectionBehavior selectionBehavior() const
void setSelectionBehavior(QAbstractItemView::SelectionBehavior behavior)


//设置为选择时只能选择单个
tree->setSelectionBehavior(QAbstractItemView::SelectItems);

behavior有三种取值:

  • QAbstractItemView::SelectItems,每次点击时只能选中单个
  • QAbstractItemView::SelectRows,每次点击时选中整行
  • QAbstractItemView::SelectColumns,每次点击时选中整列

QTreeWidgetItem

树形控件里面的条目是QTreeWidgetItem,是一个树形结构,我们对树控件增删改查就是在操作这个类,先说一下他里面的方法

  • 文本
//获取和设置item里面某一列的文本
QString QTreeWidgetItem::text(int column) const
void QTreeWidgetItem::setText(int column, const QString &text)
  •  获取和添加子节点
//添加和获取子节点
QTreeWidgetItem *QTreeWidgetItem::takeChild(int index)
void QTreeWidgetItem::addChild(QTreeWidgetItem *child)
  •  通过构造函数直接指定其父节点
QTreeWidgetItem(QTreeWidgetItem *parent, int type = Type)
QTreeWidgetItem(QTreeWidgetItem *parent, const QStringList &strings, int type = Type)
  •  通过构造函数直接指定所在树控件
QTreeWidgetItem(QTreeWidget *parent, int type = Type)
QTreeWidgetItem(QTreeWidget *parent, const QStringList &strings, int type = Type)
  •  插入子节点
//插在第几个子节点的前面
void QTreeWidgetItem::insertChild(int index, QTreeWidgetItem *child)
  •  通过构造函数直接指定插在哪个父节点的子节点前面
//插在parent节点的preceding子节点的前面
QTreeWidgetItem(QTreeWidgetItem *parent, QTreeWidgetItem *preceding, int type = Type)
  •  通过构造函数直接指定插在哪个树控件的顶级条目的前面
//插在parent树控件的preceding条目之前
QTreeWidgetItem(QTreeWidget *parent, QTreeWidgetItem *preceding, int type = Type)
  • 设置图标
//可以给每一列都设置图标
void QTreeWidgetItem::setIcon(int column, const QIcon &icon)
  •  获取子节点和子节点的数量
//根据索引获取子节点
QTreeWidgetItem *QTreeWidgetItem::child(int index) const

//获取子节点的数量
int QTreeWidgetItem::childCount() const
  •  获取父节点
QTreeWidgetItem *QTreeWidgetItem::parent() const
  • 获取所在树控件
QTreeWidget *QTreeWidgetItem::treeWidget() const

设置标题栏

  • 方法1:调用QTreeWidget的方法
//设置标题,一次性可以设置多列
void QTreeWidget::setHeaderLabels(const QStringList &labels)

//举例:
tree->setHeaderLabels({"编号","内容"});
  • 方法二:先设置一个空的标题栏,再获取到其标题栏对象(标题栏也是QTreeWidgetItem类),调用QTreeWidgetItem的方法
//设置标题栏的条目
void QTreeWidget::setHeaderItem(QTreeWidgetItem *item)
//获取标题栏
QTreeWidgetItem *QTreeWidget::headerItem() const

//QTreeWidgetItem设置文本
void QTreeWidgetItem::setText(int column, const QString &text)


//举例:
tree->setHeaderItem(new QTreeWidgetItem());//设置一个空的标题栏
tree->headerItem()->setText(0,"编号");//设置标题栏第1列的文本
tree->headerItem()->setText(1,"内容");//设置标题栏第2列的文本
//还可以继续添加

新增条目

  •  方法1:addTopLevelItem接口
//新增顶级条目
void QTreeWidget::addTopLevelItem(QTreeWidgetItem *item)


//举例:
//1、先创建条目
//新增条目
QTreeWidgetItem* item_1=new QTreeWidgetItem();
item_1->setText(0,"1");
item_1->setText(1,"清华大学");
//添加子节点
QTreeWidgetItem* item_11=new QTreeWidgetItem();
item_11->setText(0,"1001");
item_11->setText(1,"计算机学院");
item_1->addChild(item_11);
QTreeWidgetItem* item_12=new QTreeWidgetItem();
item_12->setText(0,"1002");
item_12->setText(1,"建筑学院");
item_1->addChild(item_12);
//2.添加条目
tree->addTopLevelItem(item_1);
  •  方法2:在QTreeWidgetItem的构造函数中指定父TreeWidget
//QTreeWidgetItem的构造函数中可以指定其所在树控件
QTreeWidgetItem(QTreeWidget *parent, int type = Type)


//举例:
//2.构造函数
QTreeWidgetItem* item_2=new QTreeWidgetItem(tree);
item_2->setText(0,"2");
item_2->setText(1,"北京大学");
//添加子节点
QTreeWidgetItem* item_21=new QTreeWidgetItem(item_2,{"2001","经管学院"});
QTreeWidgetItem* item_22=new QTreeWidgetItem(item_2,{"2002","理学院"});

插入条目

在指定索引处的前面插入顶级条目,如果是头插,那么index为0,如果是尾插,那么index为树控件的顶级条目数(topLevelItemCount()该方法获取)

//在指定索引处的前面插入顶级条目
void QTreeWidget::insertTopLevelItem(int index, QTreeWidgetItem *item)


//举例:
//尾部插入条目
QTreeWidgetItem* item_3=new QTreeWidgetItem({"3","复旦大学"});
QTreeWidgetItem* item_31=new QTreeWidgetItem(item_3,{"3001","文学院"});
QTreeWidgetItem* item_32=new QTreeWidgetItem(item_3,{"3002","外国语学院"});
//头插入:index为0,尾部插入:index为条目count
tree->insertTopLevelItem(tree->topLevelItemCount(),item_3);

 获取顶级条目的数目

int topLevelItemCount() const

获取顶级条目

可以根据索引获取顶级条目

QTreeWidgetItem *QTreeWidget::topLevelItem(int index) const


//举例:临时往第一个顶级条目下面添加子节点
tree->topLevelItem(0)->addChild(new QTreeWidgetItem({"1003","医学院"}));

 

给条目的某一列设置图标

//举例:给第一个顶级条目的第二列添加图标
tree->topLevelItem(0)->setIcon(1,QIcon(":/11.png"));

 

 给条目的某一列设置为控件(比如一个按钮,一个下拉列表)

//参数1:哪个节点
//参数2:哪一列
//参数3:要设置的Widget
void QTreeWidget::setItemWidget(QTreeWidgetItem *item, int column, QWidget *widget)


//举例:将清华大学设置为下拉列表
QComboBox* cbo=new QComboBox(this);
cbo->addItems({"清华大学","清华","大学"});
tree->setItemWidget(tree->topLevelItem(0),1,cbo);

 

设置选中状态

同样地,我们也可以设置选中状态,来实现选中父节点,子节点也被勾选的效果

//获取和设置条目某一列的选中状态
Qt::CheckState QTreeWidgetItem::checkState(int column) const
void QTreeWidgetItem::setCheckState(int column, Qt::CheckState state)


//举例:
        //初始化第一个条目和其子条目为未选中状态
        tree->topLevelItem(0)->setCheckState(0,Qt::Unchecked);
        for(int i=0;i<tree->topLevelItem(0)->childCount();++i)
        {
            tree->topLevelItem(0)->child(i)->setCheckState(0,Qt::Unchecked);
        }
        //绑定条目点击信号
        connect(tree,&QTreeWidget::itemClicked,tree,[=](QTreeWidgetItem* clicked_item,int i){
            //第1列被点击
            if(i==0)
            {
                //如果被点击的是顶层条目
                if(clicked_item->parent()==nullptr)
                {
                    //获取点击后的状态
                    auto check_state=clicked_item->checkState(0);

                    int child_cnt=clicked_item->childCount();
                    for(int i=0;i<child_cnt;++i)
                    {
                        if(check_state==Qt::Checked)
                        {
                            //选中后将他的子节点都选中
                            clicked_item->child(i)->setCheckState(0,Qt::Checked);
                        }
                        else if(check_state==Qt::Unchecked)
                        {
                            //未选中后将他的子节点都不选中
                            clicked_item->child(i)->setCheckState(0,Qt::Unchecked);
                        }

                    }
                }
                else//被点击的是顶层条目的子节点
                {
                    //子节点被选中的个数
                    int checked_cnt=0;

                    //遍历父节点的所有子节点
                    int child_cnt=clicked_item->parent()->childCount();
                    for(int i=0;i<child_cnt;++i)
                    {
                        if(clicked_item->parent()->child(i)->checkState(0)==Qt::Checked)
                        {
                            ++checked_cnt;
                        }
                    }

                    if(checked_cnt==0)
                    {
                        //子节点都没选中,父节点设置为未选中
                        clicked_item->parent()->setCheckState(0,Qt::Unchecked);
                    }
                    else if(checked_cnt==clicked_item->parent()->childCount())
                    {
                        //都选中了,父节点设置为选中
                        clicked_item->parent()->setCheckState(0,Qt::Checked);
                    }
                    else
                    {
                        //部分选中,父节点设置为半选
                        clicked_item->parent()->setCheckState(0,Qt::PartiallyChecked);
                    }
                }
            }
        });

 

获取选中的节点 

能够获取到上面被选中的节点

QList<QTreeWidgetItem *> QTreeWidget::selectedItems() const

常用信号

英文名的意思很清晰了

/*
1、currentItemChanged()
2、itemActivated()
3、itemChanged()
4、itemClicked()
5、itemCollapsed()收起
6、itemDoubleClicked
7、itemEntered
8、itemExpanded展开,展开后动态生成子节点,需要先遍历条目清空原来的子节点
9、itemPressed
*/

常用槽函数

//收缩条目
[slot] void QTreeWidget::collapseItem(const QTreeWidgetItem *item)

//展开条目
[slot] void QTreeWidget::expandItem(const QTreeWidgetItem *item)


//举例:鼠标移到条目上面,展开条目
//需要打开鼠标追踪
tree->setMouseTracking(true);
//绑定进入条目信号
connect(tree,&QTreeWidget::itemEntered,tree,[=](QTreeWidgetItem* item){
     tree->expandItem(item);
});

 样式表

/*
1、行列样式(交替背景行)
setAlternatingRowColors(true);先要打开这个属性
alternate-background-color:
2、条目通常样式、条目被选中、鼠标悬停样式
QTreeWidget::item{}
QTreeWidget::item:hover{}
QTreeWidget::item:select{}
3、条目收缩和展开时图片替换
3.1 QTreeWidget::branch:has-siblings:!adjoins-item {border-image: url(vline.png)}
3.2 QTreeWidget::branch:has-siblings:adjoins-item {border-image:url(branch-more.png)}
3.3 QTreeWidget::branch:!has-children:!has-siblings:adjoins-item{border-image: url(branch-end.png)}
3.4 QTreeWidget::branch:has-children:!has-siblings:closed,QTreeWidget::branch:closed:has-children:has-siblings {border-image:none;image:url(branch-closed.png)}
3.5 QTreeWidget::branch:open:has-children:!has-siblings,QTreeWidget::branch:open:has-children:has-siblings {border-image:none;image:url(branch-open.png)}
4、标题样式
QHeaderView::section{}
*/

说一下3的样式

美工提供这些图

 学习链接:https://github.com/0voice

;