最终实现的效果:
1.创建QTreeWidget控件
创建QTreeWidget控件,添加父节点,父节点下添加子节点,通过复选框进行选择。
1 //初始化控件函数
2 void MainWindow::init()
3 {
4 QTreeWidget *newTree = new QTreeWidget(this); //在当前的类里创建一个树控件
5 newTree->headerItem()->setText(0,QString()); //设置表头为空
6 newTree->setGeometry(50,50,400,240); //设置起始坐标和大小
7 QStringList hraders;
8 hraders<<" "<<"类型"<<"时间";
9 newTree->setHeaderLabels(hraders); //添加树表的表头
10 QTreeWidgetItem *item1 = new QTreeWidgetItem(newTree); //创建第一个父节点
11 item1->setText(0,"111");
12 item1->setCheckState(0,Qt::Unchecked); //添加复选框,起始为未勾选
13 item1->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled);
14 //Qt::ItemIsSelectable表示可选的
15 //Qt::ItemIsUserCheckable项目上是否有复选框
16 //Qt::ItemIsEnabled 项目上是否没有被禁用(Enabled可用/Disabled禁用)
17 QTreeWidgetItem *item1_1 = new QTreeWidgetItem(item1); //添加子节点
18 item1_1->setText(0,"111_111");
19 item1_1->setCheckState(0,Qt::Unchecked);
20 item1_1->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled);
21
22 QTreeWidgetItem *item1_2 = new QTreeWidgetItem(item1);
23 item1_2->setText(0,"111_222");
24 item1_2->setCheckState(0,Qt::Unchecked);
25 item1_2->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled);
26
27 QTreeWidgetItem *item1_3 = new QTreeWidgetItem(item1);
28 item1_3->setText(0,"111_333");
29 item1_3->setCheckState(0,Qt::Unchecked);
30 item1_3->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled);
31
32 QTreeWidgetItem *item2 = new QTreeWidgetItem(newTree);
33 item2->setText(0,"222");
34 item2->setCheckState(0,Qt::Unchecked);
35 item2->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled);
36
37 QTreeWidgetItem *item2_1 = new QTreeWidgetItem(item2);
38 item2_1->setText(0,"222_222");
39 item2_1->setCheckState(0,Qt::Unchecked);
40 item2_1->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled);
41 connect(newTree,SIGNAL(itemClicked(QTreeWidgetItem *, int)),this,SLOT(treeCheck(QTreeWidgetItem *, int)));
42 //注意:信号一定只声明变量类型,不要加变量名,是否会报错,找不到该信号
43 }
2.类中定义的函数
槽函数:
1 public slots:
2 void treeCheck(QTreeWidgetItem *item, int column);
与itemClicked信号想连接,当有触发信号时,会传递参数,判断操作的是哪个节点。
1 pubilc:
2 void PartiallyCheck(QTreeWidgetItem *item);
3.槽函数的实现
1 void MainWindow::treeCheck(QTreeWidgetItem *item, int column)
2 {
3 if(Qt::Checked == item->checkState(0)) //若被选中
4 {
5 int count = item->childCount(); //得到选中的子节点个数
6 if(count>0) //若大于0,说明选中的是父节点,则将全部的子节点选中
7 {
8 for (int i = 0;i<count;i++) {
9 item->child(i)->setCheckState(0,Qt::Checked);
10 }
11 }
12 else { //否则选中的是子节点
13 PartiallyCheck(item); //将节点传到函数中进行其他操作
14 }
15 }
16 else if(Qt::Unchecked == item->checkState(0)){ //没有被选中
17 int count = item->childCount();
18 if(count>0)
19 {
20 for (int i = 0;i<count;i++) {
21 item->child(i)->setCheckState(0,Qt::Unchecked);
22 }
23 }
24 else {
25 PartiallyCheck(item);
26 }
27 }
28 }
29
30 void MainWindow::PartiallyCheck(QTreeWidgetItem *item)
31 {
32 //得到节点的父节点,首先判断是否为空,为空说明是父节点,则直接退出,若不加判断会造成程序异常退出。
33 QTreeWidgetItem *parent = item->parent();
34 if(parent==nullptr)
35 return;
36 int selectedCount = 0; //记录被选中的子节点个数
37 int count = parent->childCount(); //记录子节点个数
38 for (int i = 0;i<count ;i++) { //父节点下的所有子节点,记录选中的子节点个数
39 if(parent->child(i)->checkState(0)==Qt::Checked)
40 selectedCount++;
41 }
42 if(selectedCount<=0) //等于0说明没有子节点被选中,则将父节点取消选中
43 parent->setCheckState(0,Qt::Unchecked);
44 else if(selectedCount>0&&selectedCount<count) //若大于0且小于总的子节点数,说明选中了一部分,则将父节点设置为半选中
45 parent->setCheckState(0,Qt::PartiallyChecked);
46 else { //否则,全选中
47 parent->setCheckState(0,Qt::Checked);
48 }
49 }