//1、调用相应的构造函数,直接指定新结点的父结点QTreeWidgetItem childItem(&item);//2、先创建一个新结点,调用 QTreeWidgetItem 类提供的 addChild() 方法,可以为某个结点添加子结点。QTreeWidgetItem childItem2;item2.addChild(&childItem2);
除此之外,还有其它添加结点的方法,例如使用QList<QTreeWidgetItem *> items
一次性向树形控件中添加多个顶层结点或者子结点:
//1、调用相应的构造函数,直接指定新结点的父结点
QTreeWidgetItem childItem(&item);
//2、先创建一个新结点,调用 QTreeWidgetItem 类提供的 addChild() 方法,可以为某个结点添加子结点。
QTreeWidgetItem childItem2;
item2.addChild(&childItem2);
Qt 对 C++ STL 库中的容器进行了更好的封装,QList 容器就是其中之一。通过先将 item 和 item2 添加到 items 容器中,然后再将 items 传递给 treeWidget 对象的 addTopLevelItems() 方法,就可以将 items 容器中的所有结点添加到 treeWidget 控件中,作为该控件的顶层结点。
通过将装满结点的 QList 容器借助 QTreeWidgetItem 类提供的 addChildren() 方法,可以添加多个子结点。这里不再给出实例代码,感兴趣的读者可自行尝试实现。
2) 给结点添加图标
对于每个 QTreeWidgetItem 类的结点,除了可以放置文本信息外,还可以添加 icon 图标。
【实例一】
#include <QApplication>
#include <QWidget>
#include <QTreeWidget>
#include <QTreeWidgetItem>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget widget;
widget.setWindowTitle("MyTreeWidget控件");
QTreeWidget treeWidget(&widget);
QTreeWidgetItem item;
item.setText(0,"http://c.biancheng.net");
item.setIcon(0,QIcon("D:\\favicon.ico"));
treeWidget.addTopLevelItem(&item);
widget.show();
return a.exec();
}
假设 D 盘存储着一个名为 favicon.ico 的 icon 图标,程序执行结果为:
图 3 带 icon 的结点
3) 给结点添加复选框
所谓复选框,举个简单的例子,在【实例一】程序的第 14 行插入一行代码:
item.setCheckState(0,Qt::Unchecked);
再次执行程序,输出结果为:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J1IwSuDJ-1669280924200)(http://c.biancheng.net/uploads/allimg/211028/16394R2J-3.gif)]
图 4 带复选框的结点
对比图 3 和图 4 不难发现,之前放置 icon 的位置被一个方框占据了。这个方框是可以被选择的,而且当同时存在多个方框时,用户可以根据需要选择性地选中多个方框,这样的方框称为复选框。
默认情况下,QTreeWidgetItem 结点不显示复选框,通过调用 setCheckState() 方法,可以使结点自带的复选框显现出来。复选框的状态有 3 种,如下图所示:
图 5 复选框的 3 种状态
- Qt::Unchecked:未选中状态,对应图 5 中的第一种情况;
- Qt::Checked:选中状态,对应图 5 中的第二种情况;
- Qt::PartiallyChecked:部分选中状态,对应图 5 中的第三种情况。
所谓部分选中状态,是指当该结点下包含多个带复选框的子节点时,如果用户只选中了其中一部分子结点,那么通常将该结点设置为部分选中状态。
4) 多列树形控件
上文给大家创建的 QTreeWidget 控件,都只包含一列。图 2~5 中,各个 QTreeWdiget 控件中都显示一个数字 1,就是因为控件中只包含 1 列,数字 1 就是这一列的表头。根据需要,QTreeWidget 控件中每一行可以存放多列结点。
【实例二】
#include <QApplication>
#include <QWidget>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QStringList>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget widget;
widget.setWindowTitle("MyTreeWidget控件");
widget.resize(600,300);
QTreeWidget treeWidget(&widget);
//设置列数
treeWidget.setColumnCount(3);
treeWidget.resize(600,300);
//添加顶层结点
QTreeWidgetItem topItem;
topItem.setText(0,"教程");
treeWidget.addTopLevelItem(&topItem);
//添加子结点
QStringList c;
c << "C语言教程" << "http://c.biancheng.net/c/" <<"已完成";
QTreeWidgetItem childItem1(&topItem,c);
QStringList qt;
qt << "Qt教程" << "http://c.biancheng.net/qt/" <<"未完成";
QTreeWidgetItem childItem2(&topItem,qt);
QStringList python;
python << "Python教程" << "http://c.biancheng.net/python/" <<"已完成";
QTreeWidgetItem childItem3(&topItem,python);
widget.show();
return a.exec();
}
程序运行结果为:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aZnX7nMm-1669280924203)(http://c.biancheng.net/uploads/allimg/211028/16394W519-5.png)]
图 6 多列树形控件
默认情况下,每一列的表头是当前列的列号。必要的时候,我们还可以指定每一列的表头。例如:
QStringList top;
top << "教程" << "网址" <<"完成状态";
treeWidget.setHeaderLabels(top);
由此,图 6 中各个列的表头就依次变成了“教程”、“网址”和“完成状态”。读者可以将上述 3 行代码添加到实例二第 16 行的位置,然后再次运行程序查看执行结果。
此外,QTreeWidget 控件默认会显示每一列的表头,通过调用从 QTreeView 父类继承过来的 setHeaderHidden() 方法,可以将表头隐藏起来。例如:
treeWidget.setHeaderHidden(true);
当参数值为 true 时,表示将表头隐藏起来,反之则表示不隐藏表头。
5) QTreeWidget中添加其它控件
QTreeWidgetItem 结点除了可以显示文本信息、icon图标、复选框等基本内容外,还可以容纳其它的一些的控件,例如输入框、按钮等。
QTreeWidget 类提供有 setItemWidget() 方法,可以将其它控件添加到指定列的结点中:
void QTreeWidget::setItemWidget(QTreeWidgetItem *item, int column, QWidget *widget)
item 表示容纳 widget 控件的结点,column 参数用于指定将 widget 添加到 item 第几列的位置上。
举个例子:
#include <QApplication>
#include <QWidget>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QStringList>
#include <QTableWidget>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget widget;
widget.setWindowTitle("MyTreeWidget控件");
widget.resize(600,300);
QTreeWidget treeWidget(&widget);
//设置列数
treeWidget.resize(600,300);
//添加顶层结点
QTreeWidgetItem topItem;
treeWidget.addTopLevelItem(&topItem);
//创建表格控件
QTableWidget TableWidget(4,3);
//设置表格中每一行的内容
TableWidget.setItem(0,0,new QTableWidgetItem("C语言教程"));
TableWidget.setItem(0,1,new QTableWidgetItem("http://c.biancheng.net/c/"));
TableWidget.setItem(0,2,new QTableWidgetItem("已更新完毕"));
TableWidget.setItem(1,0,new QTableWidgetItem("Qt教程"));
TableWidget.setItem(1,1,new QTableWidgetItem("http://c.biancheng.net/qt/"));
TableWidget.setItem(1,2,new QTableWidgetItem("正在更新"));
TableWidget.setItem(2,0,new QTableWidgetItem("C++教程"));
TableWidget.setItem(2,1,new QTableWidgetItem("http://c.biancheng.net/cplus/"));
TableWidget.setItem(2,2,new QTableWidgetItem("已更新完毕"));
//将表格控件作为结点内容
treeWidget.setItemWidget(&topItem,0,&TableWidget);
widget.show();
return a.exec();
}
程序运行结果为:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ybNvHW0S-1669280924204)(http://c.biancheng.net/uploads/allimg/211028/16394QO9-6.png)]
图 7 QTreeWidget添加其它控件
QTreeWidget信号和槽
QTreeWidget 控件提供了很多信号函数,可以捕捉用户的诸多动作,例如点击或双击了某个结点、某个结点被修改等等,如下罗列了几个常用的信号函数:
//用户单击某个结点时,会触发此信号函数
void QTreeWidget::itemClicked(QTreeWidgetItem *item, int column)
//用户双击某个结点时,会触发此信号函数
void QTreeWidget::itemDoubleClicked(QTreeWidgetItem *item, int column)
//当某个结点的内容被修改时,会触发此信号函数
void QTreeWidget::itemChanged(QTreeWidgetItem *item, int column)
//当用户选择其它结点时,会触发此信号函数
void QTreeWidget::currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
同时,QTreeWidget 还提供了很多槽函数,例如:
//控件树形控件中的所有结点
void QTreeWidget::clear()
//折叠指定结点所有的子结点
void QTreeWidget::collapseItem(const QTreeWidgetItem *item)
//展开指定结点所有的子结点
void QTreeWidget::expandItem(const QTreeWidgetItem *item)
这里给大家举个简单的例子,实际场景中当某个结点的复选框被选中时,它的所有子结点也应该同时被选中。这个功能就可以利用 QTreeWidget 的信号和槽来实现。
//main.cpp
#include <QApplication>
#include <QWidget>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QStringList>
#include <QTableWidget>
//自定义槽函数
class MyWidget:public QWidget{
Q_OBJECT
public slots:
void treeWidgetClicked(QTreeWidgetItem * item);
};
//接收 itemClicked() 信号函数传递过来的 item 参数
void MyWidget::treeWidgetClicked(QTreeWidgetItem *item){
//遍历 item 结点所有的子结点
for(int i=0;i<item->childCount();i++){
//找到每个子结点
QTreeWidgetItem *childItem = item->child(i);
//将子结点的选中状态调整为和父结点相同
childItem->setCheckState(0,item->checkState(0));
}
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyWidget widget;
widget.setWindowTitle("MyTreeWidget控件");
widget.resize(600,300);
QTreeWidget treeWidget(&widget);
//设置列数
treeWidget.setColumnCount(3);
treeWidget.resize(600,300);
//添加顶层结点
QTreeWidgetItem topItem;
topItem.setText(0,"教程");
topItem.setCheckState(0,Qt::Unchecked);
treeWidget.addTopLevelItem(&topItem);
//添加子结点
QStringList c;
c << "C语言教程" << "http://c.biancheng.net/c/" <<"已完成";
QTreeWidgetItem childItem1(&topItem,c);
childItem1.setCheckState(0,Qt::Unchecked);
![img]()
![img]()