QT带复选框的树节点的勾选逻辑
QT5.12.6
.h
#pragma once
#include <QDialog>
#include <QDebug>
#include <QStandardItemModel>
#include "ui_Demo.h"
class Demo : public QDialog
{
Q_OBJECT
public:
Demo(QWidget *parent = Q_NULLPTR);
private slots:
void treeItemChanged(QStandardItem*);
void treeItem_CheckAllParent(QStandardItem* item, bool checked);
void treeItem_CheckAllChild(QStandardItem*,bool checked);
private:
Ui::DemoClass ui;
QStandardItemModel* model = nullptr;
};
.cpp
#include "Demo.h"
Demo::Demo(QWidget *parent)
: QDialog(parent)
, model(new QStandardItemModel)
{
ui.setupUi(this);
ui.treeView->setModel(model);
QStandardItem* root = new QStandardItem("parent");
root->setCheckable(true);
root->setUserTristate(true);
model->appendRow(root);
QStandardItem* child1 = new QStandardItem("child1");
QStandardItem* child1_1 = new QStandardItem("child1");
QStandardItem* child1_2 = new QStandardItem("child2");
child1->setCheckable(true);
child1->setUserTristate(true);
child1_1->setCheckable(true);
child1_2->setCheckable(true);
child1->appendRow(child1_1);
child1->appendRow(child1_2);
QStandardItem* child2 = new QStandardItem("child2");
QStandardItem* child2_1 = new QStandardItem("child1");
QStandardItem* child2_2 = new QStandardItem("child2");
child2->setCheckable(true);
child2->setUserTristate(true);
child2_1->setCheckable(true);
child2_2->setCheckable(true);
child2->appendRow(child2_1);
child2->appendRow(child2_2);
root->appendRow(child1);
root->appendRow(child2);
connect(model, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(treeItemChanged(QStandardItem*)));
ui.treeView->expandAll();
}
void Demo::treeItemChanged(QStandardItem* item) {
int checkState = item->checkState();
if (checkState != Qt::PartiallyChecked) {
for (int i = 0; i < item->rowCount(); i++)
treeItem_CheckAllChild(item->child(i), checkState);
if (item->parent()) treeItem_CheckAllParent(item->parent(), checkState);
}
}
void Demo::treeItem_CheckAllChild(QStandardItem* item, bool checked) {
item->setCheckState(checked ? Qt::Checked : Qt::Unchecked);
for (int i = 0; i < item->rowCount(); i++)
treeItem_CheckAllChild(item->child(i), checked);
}
void Demo::treeItem_CheckAllParent(QStandardItem* item, bool checked) {
double checkCount = 0;
for (int i = 0; i < item->rowCount(); i++) {
int checkState = item->child(i)->checkState();
switch (checkState) {
case Qt::Checked:
checkCount++;
break;
case Qt::PartiallyChecked:
checkCount+=0.5;
break;
}
}
if (checkCount == item->rowCount()) item->setCheckState(Qt::Checked);
else if (checkCount == 0) item->setCheckState(Qt::Unchecked);
else item->setCheckState(Qt::PartiallyChecked);
if(item->parent()) treeItem_CheckAllParent(item->parent(), checked);
}
.ui
拖拽一个QTreeView
如果有更加优化的做法,请在下方评论进行交流,2021.3.30