在工作中这个困扰了好久,在我不懈的坚持下终于弄清楚
https://blog.csdn.net/czyt1988/article/details/18996407
尘中远阁下的多选功能感觉树要多选套用这段代码就完美
首选用来尘中远阁下的多选的关联
具体代码如下:
可以算作经典通用代码
其中勾选之后的项如果要实现具体的功能
应该在勾选或者不够选之后给具体所在的树发送一个点击信号使其得到关联
在本例中 我给我的树发送了一个点击信号
若点击我所关联树的具体功能可以得到实现
***这一步很重要!!!***直接导致我的功能是否能用,而不是只完成形态的变化,而功能不能实现
item->setCheckState(check ? Qt::Checked : Qt::Unchecked);
emit m_deviceTree->clicked(item->index());
// 父子节点复选框自动关联实现
void CBroadcastDlg::treeItemChanged(QStandardItem *item)
{
// 先判断是否有该项
if (nullptr == item)
{
return;
}
// 如果条目是存在复选框,那么进行下面的操作
if (item->isCheckable())
{
// 获取当前选择状态
Qt::CheckState state = item->checkState();
if (item->isTristate())
{
// 如果条目是三态的,说明可以对目录进行全选和全不选的设置
if (state != Qt::PartiallyChecked)
{
// 当前是选中状态,需要对其子项目进行全选
treeItem_checkAllChild(item, state == Qt::Checked ? true : false);
}
}
else
{ // 说明是两态的,两态会对父级的三态有影响
// 判断兄弟节点的情况
treeItem_CheckChildChanged(item);
}
}
}
// 递归设置所有的子项目为全选或全不选状态
// item当前项目
// check true时为全选,false时全不选
void CBroadcastDlg::treeItem_checkAllChild(QStandardItem *item, bool check)
{
// 用于使子节点全选的函数
if (nullptr == item)
{
return;
}
int rowCount = item->rowCount();
for (int i = 0; i < rowCount; ++i)
{
QStandardItem *childItems = item->child(i);
treeItem_checkAllChild_recursion(childItems, check); // 递归子项的函数
}
if (item->isCheckable())
{
item->setCheckState(check ? Qt::Checked : Qt::Unchecked);
emit m_deviceTree->clicked(item->index());
}
}
// 递归看其子项是否勾选
void CBroadcastDlg::treeItem_checkAllChild_recursion(QStandardItem *item, bool check)
{
if (nullptr == item)
{
return;
}
int rowCount = item->rowCount();
for (int i = 0; i < rowCount; ++i)
{
QStandardItem *childItems = item->child(i);
treeItem_checkAllChild_recursion(childItems, check);
}
if (item->isCheckable())
{
item->setCheckState(check ? Qt::Checked : Qt::Unchecked);
emit m_deviceTree->clicked(item->index()); // 当我状态改变后给设备树添加一个点击效果
}
}
// 根据子节点的改变,更改父节点的选择情况
void CBroadcastDlg::treeItem_CheckChildChanged(QStandardItem *item)
{
if (nullptr == item)
{
return;
}
Qt::CheckState sibLingState = checkSibling(item); // 获取到兄弟节点的状态
QStandardItem *parentItem = item->parent();
if (nullptr == parentItem)
{
return;
}
if (Qt::PartiallyChecked == sibLingState)
{
if (parentItem->isCheckable() && parentItem->isTristate())
{
parentItem->setCheckState(Qt::PartiallyChecked);
}
}
else if (Qt::Checked == sibLingState)
{
if (parentItem->isCheckable())
{
parentItem->setCheckState(Qt::Checked);
}
}
else
{
if (parentItem->isCheckable())
{
parentItem->setCheckState(Qt::Unchecked);
}
}
treeItem_CheckChildChanged(parentItem);
}
/*
此函数递归函数,首先判断的是父级是否到达顶层
到达底层作为递归的结束,通过函数checkSibling
判断当前的兄弟节点的具体情况,
*/
// 查看兄弟节点的情况,如果都选中返回Qt::Checked,都不选中Qt::Unchecked,
// 不完全选中partiall
Qt::CheckState CBroadcastDlg::checkSibling(QStandardItem *item)
{
// 先通过父节点获取兄弟节点
QStandardItem *parent = item->parent();
if (nullptr == parent)
{
return item->checkState();
}
int brotherCount = parent->rowCount();
int checkedCount(0), unCheckedCount(0);
Qt::CheckState state;
for (int i = 0; i < brotherCount; ++i)
{
QStandardItem *siblingItem = parent->child(i);
state = siblingItem->checkState();
if (Qt::PartiallyChecked == state)
{
return Qt::PartiallyChecked;
}
else if (Qt::Unchecked == state)
{
++unCheckedCount;
}
else
{
++checkedCount;
}
if (checkedCount > 0 && unCheckedCount > 0)
{
return Qt::PartiallyChecked;
}
}
if (unCheckedCount > 0)
{
return Qt::Unchecked;
}
return Qt::Checked;
}