QT树型视图的多选功能

在工作中这个困扰了好久,在我不懈的坚持下终于弄清楚
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;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值