Qt QTreeView实现三态复选框

发布时间 2023-07-25 17:18:43作者: lxg_7105

//参考:https://dgrt.cn/a/1328707.html?action=onClick

void QtWidgetsApplication1::initTreeView()
{
ui.treeView->setEditTriggers(QTreeView::NoEditTriggers);
//自定义右键菜单
this->setContextMenuPolicy(Qt::CustomContextMenu);
//最喜欢用的model, 不喜欢自己写model浪费时间
_model = new QStandardItemModel(this);
//隐藏头部
ui.treeView->setHeaderHidden(true);
//水平头部描述(已经被隐藏了)
QStringList headList;
headList << "item";
_model->setHorizontalHeaderLabels(headList);
_model->setColumnCount(headList.size());
auto root = new QStandardItem(QString("Root"));
root->setCheckable(true);
_model->appendRow(root);
for (int i = 0; i < 20; ++i) {
auto item = new QStandardItem(QString("%1").arg(i));
item->setCheckable(true);
int cRowCount = 2;/*rand() %300;*/
for (int j = 0; j < cRowCount; ++j) {
auto cItem = new QStandardItem(QString("[%1:%2]").arg(i).arg(j));
cItem->setCheckable(true);
item->appendRow(cItem);
for (int n = 0; n < 4; ++n) {
auto nItem = new QStandardItem(QString("[%1:%2]:[%3]").arg(i).arg(j).arg(n));
nItem->setCheckable(true);
cItem->appendRow(nItem);
for (int m = 0; m < 4; ++m) {
auto mItem = new QStandardItem(QString("[%1:%2]:[%3][%4]").arg(i).arg(j).arg(n).arg(m));
mItem->setCheckable(true);
nItem->appendRow(mItem);
}
}
}
item->setText(QString("%1 (%2)").arg(item->text()).arg(item->rowCount()));
root->appendRow(item);
//_model->appendRow(item);
}
connect(_model, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(slotItemChanged(QStandardItem*)));
ui.treeView->setModel(_model);
}

void QtWidgetsApplication1::slotItemChanged(QStandardItem* item)
{
if (!item)
return;
_model->blockSignals(true);
setChildItems(item, item->checkState() == Qt::Checked ? true : false);
setParentItems(item, item->checkState() == Qt::Checked ? true : false);
_model->blockSignals(false);
ui.treeView->viewport()->update();
}

bool QtWidgetsApplication1::setParentItems(QStandardItem* item, bool check)
{
if (!item || !item->parent()) return false;
QStandardItem* parentItem = item->parent();
int rowCount = parentItem->rowCount();
Qt::CheckState checkState = check ? Qt::Checked : Qt::Unchecked;
int checkedCount = 0;
int uncheckedCount = 0;
for (int i = 0; i < rowCount; ++i) {
QStandardItem* childItem = parentItem->child(i);
if (childItem->checkState() == Qt::Checked && check) {
++checkedCount;
}
else if (childItem->checkState() == Qt::Unchecked && !check) {
++uncheckedCount;
}
else {
checkState = Qt::PartiallyChecked;
break;
}
}
if (checkedCount != rowCount && uncheckedCount != rowCount) {
checkState = Qt::PartiallyChecked;
}
parentItem->setCheckState(checkState);
setParentItems(parentItem, check);
return true;
}

bool QtWidgetsApplication1::setChildItems(QStandardItem* item, bool check)
{
if (!item) return false;
item->setCheckState(check ? Qt::Checked : Qt::Unchecked);
int rowCount = item->rowCount();
for (int i = 0; i < rowCount; ++i) {
QStandardItem* childItem = item->child(i);
setChildItems(childItem, check);
}
return true;
}
//启用/禁用 item及子项
bool QtWidgetsApplication1::setChildItemsEnabled(QStandardItem* item, bool enabled)
{
if (!item) return false;
item->setEnabled(enabled);
int rowCount = item->rowCount();
for (int i = 0; i < rowCount; ++i) {
QStandardItem* childItem = item->child(i);
setChildItemsEnabled(childItem, enabled);
}
return true;
}