树控件跟表格控件类似,也可以有多列,也可以只有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