这是以前做过的例子,之前是参考的网上的例子,觉得遍历次数太多,效率不行。自己尝试优化修改了一番。小试牛刀,欢迎拍砖。效果如下图:

示例数据做得比较粗糙。来看看是怎么实现的吧。

功能

  • 勾选树控件的节点,其子节点全部选中或全部取消选中
  • 父节点选中或者部分选中

实现

QTreeWidgetItem的复选框,可以通过setCheckState(int column,Qt::CheckState state)方法调出。

勾选状态的改变,通过itemChanged(QTreeWidgetItem *item,int column)信号触发。

connect(ui->treeWidget,&QTreeWidget::itemChanged,this,&Widget::ItemCheckChanged);

节点勾选状态的改变,1,需要改变其子节点的状态;2 ,需要改变父节点的状态;

子节点的状态改变,通过一个递归就可以实现,要么全部勾选,要么全部不勾选:

void Widget::UpdateChild(QTreeWidgetItem *itm)
{int childCount = itm->childCount();if(childCount > 0){for(int i = 0; i < childCount; i++){itm->child(i)->setCheckState(0,itm->checkState(0));if(itm->child(i)->childCount() > 0)UpdateChild(itm->child(i));}}
}

父节点的状态改变稍稍有点麻烦。存在如下几种情况:

(这个图,我实在是画的难看,就不画了,用这张勉强看看)

1. 子节点勾选,兄弟节点不勾,则父节点半勾选,根节点半勾选;

2. 子节点勾选,兄弟节点勾选,则父节点勾选,根节点待定(如果存在父节点的兄弟,需要递归判断);

3. 子节点不勾选,兄弟节点不勾选,则父节点不勾选,根节点待定(同上);

4. 子节点不勾选,兄弟节点勾选,则父节点半勾选,根节点半勾选。

由上可知,1,4两种情况是确定的,不管有多少层,父节点,根节点一定是半勾选,直接递归往上设置就可以了:

void Widget::SetParentPartiallyChecked(QTreeWidgetItem *itm)
{QTreeWidgetItem *parent = itm->parent();if(parent){parent->setCheckState(0,Qt::PartiallyChecked);SetParentPartiallyChecked(parent);}
}

剩余2,3这两种情况,需要逐层遍历往上判断。

通过获取子节点及兄弟节点的勾选个数与总的节点数进行判断:

1. 勾选数 == 0时,父不勾;

2.勾选数 > 0且 勾选数 < 节点总数时,父半勾;

3.勾选数 == 节点总数时,父勾选。

代码如下:

void Widget::UpdateParent(QTreeWidgetItem *itm)
{QTreeWidgetItem *parent = itm->parent();if(parent){int checkedCount = 0;int itemCount = parent->childCount();for(int i = 0; i < itemCount; i++){QTreeWidgetItem *item = parent->child(i);if(Qt::Checked == item->checkState(0))checkedCount++;}if(checkedCount <= 0 ){parent->setCheckState(0,Qt::Unchecked);}else if(checkedCount > 0 && checkedCount < itemCount  ){parent->setCheckState(0,Qt::PartiallyChecked);SetParentPartiallyChecked(parent);return;}else if(checkedCount > 0 && checkedCount == itemCount){parent->setCheckState(0,Qt::Checked);}// Recursively iterate upUpdateParent(parent);}
}

看起来好像没问题了,但是忽略了这种情况,导致如下问题:

根节点应该是半勾选状态,但实际是未勾选。

这是因为在“勾选数 == 0”这种情况下,忽略了对半勾选状态的判断。

“勾选数 == 0”时,还存在两种情况:

1. 半勾选数 ==0 时,父不勾;

2. 半勾选数 > 0时,父半勾。

增加半勾选数量,及相应判断,修改代码如下:

void Widget::UpdateParent(QTreeWidgetItem *itm)
{QTreeWidgetItem *parent = itm->parent();if(parent){int checkedCount = 0;int patiallyCount = 0;int itemCount = parent->childCount();for(int i = 0; i < itemCount; i++){QTreeWidgetItem *item = parent->child(i);if(Qt::Checked == item->checkState(0))checkedCount++;else if(Qt::PartiallyChecked == item->checkState(0))patiallyCount++;}if(checkedCount <= 0 ){if(patiallyCount > 0)goto Partially;elseparent->setCheckState(0,Qt::Unchecked);}else if(checkedCount > 0 && checkedCount < itemCount  ){Partially:parent->setCheckState(0,Qt::PartiallyChecked);SetParentPartiallyChecked(parent);return;}else if(checkedCount > 0 && checkedCount == itemCount){parent->setCheckState(0,Qt::Checked);}// Recursively iterate upUpdateParent(parent);}
}

这样就覆盖了刚刚忽略的情况,实现了gif图的效果。

之前的代码,设置父节点,都是一层层的往上遍历,其实是可以排除一些不必要的遍历。优化整体效率。

全部代码下载地址:

由于csdn的积分制度,原来的资源涨到了9分,就重新上传了一份,结果还是5分起步。唉,能少一点是一点吧。更新一下链接。

https://download.csdn.net/download/xiaosha00000/11212101

这只是自己的一点点拙见,希望有更好的思路,能提出来,相互提高。感谢!

Qt,优化QTreeWidget的三态:勾选,未勾选,半勾选相关推荐

  1. Qt 优化QTreeWidget的三态:勾选,未勾选,半勾选

    这是以前做过的例子,之前是参考的网上的例子,觉得遍历次数太多,效率不行.自己尝试优化修改了一番.小试牛刀,欢迎拍砖.效果如下图: 示例数据做得比较粗糙.来看看是怎么实现的吧. 功能 勾选树控件的节点, ...

  2. element-ui 表格使用多选 如何回显打勾

    项目需求: 选择表格中的数据 点击按钮 出现弹框,弹框中显示表格上所选中的数据. 点击弹框中的删除,该行数据删除,对应的表格上也要取消掉勾选. 表格渲染代码 <el-tableheight=&q ...

  3. Qt编写高仿苹果MAC电脑输入法(支持触摸滑动选词)

    最近有个朋友找我定制一个输入法,需要高仿一个苹果MAC电脑的输入法,MAC操作系统的审美无疑是相当棒的,于是乎直接拿以前的输入法高仿了一个,由于之前有做过输入法这块的开发,而且改进了四年,各种需求都遇 ...

  4. Qt编写输入法源码V2019,未采用Qt系统层输入法框架,独创输入切换机制

    Qt编写输入法源码V2019 未采用Qt系统层输入法框架,独创输入切换机制. 纯QWidget编写,支持任何目标平台(亲测windows.linux.嵌入式linux等),支持任意Qt版本(亲测Qt4 ...

  5. 方形勾选框html,Selenium之勾选框操作

    勾选框操作: 所谓勾选框,也可以叫复选框,意思是可以勾选一个及以上或全部勾选.勾选框的图标一般都是方形的. 复选框勾选一般分为三种情况: ①勾选单个框,我们直接用元素定位的方式定位到点击即可. ②勾选 ...

  6. 在reader中勾选pdf复选框_绝对可勾选的在WORD 2003中加入复选框的方法

    绝对可勾选的在 word 2003 中加入复选框的方法 方法一: 要在 word 2003 中加入复选框,最好是使用"控件工具箱"来完成. 具体方法是: 打开 Word ,依次点击 ...

  7. java 复选框 背景色_将多选框选中时打勾的颜色

    body { font-size:12px; } .checkbox { width:12px; height:12px; background-image:url(http://ucren.com/ ...

  8. Qt使用MSVC编译器关闭“C4100:未引用的形参”警告的方法

    Qt使用MSVC编译器关闭"C4100:未引用的形参"警告的方法 [问题描述] 在C++中,经常会定义一些虚函数作为接口类,这些虚函数本身基本是空函数,由派生类覆盖出具体的实现.一 ...

  9. antd树型选择控件选择父级_element的tree树形菜单回显、父级半勾选

    解决的问题: 1. 当拿到了后台的数据,使用id去渲染选中的节点时,如果父级id包含在id数组里,而此id下面的子节点只有部分选中的情况下,此父级id下面得所有子节点全部被选中了. 2. 当需要保存当 ...

最新文章

  1. 一看就知道的Java8日期处理全方位实践
  2. centos格式化优盘命令_centos 磁盘分区、格式化及挂载
  3. redis 的 HyperLogLog
  4. API编程基本控件使用
  5. (android)system ui 内存优化
  6. 【论文速读】ChengLin_Liu_ICCV2017_Deep_Direct_Regression_for_Multi-Oriented_Scene_Text_Detection...
  7. 安装keepalived执行make报错的解决方法
  8. H5之微信授权登陆 (uniapp网页版微信授权登录)
  9. myeclipse配置多个domain的方法
  10. windows进程详解
  11. 【What if 系列】拖住那架飞机!
  12. 计算机网络重要知识点总结(期末复习笔记)
  13. CAD属性编辑操作——回退、重作
  14. 基于Python实现语法分析
  15. 微信小程序开发实战 ②①(网路请求Promise化)
  16. 《Android 开发入门与实战(第二版)》——6.10节本章小结
  17. 二年级机器人伙伴看图写话_机器人的看图写话范文-看图写话机器人老师?
  18. 【推论】 对称点公式
  19. 飞塔30E防火墙忘记密码,重置密码
  20. 用于提高车牌识别的单幅噪声图像去噪和校正

热门文章

  1. JSP和HTML的区别
  2. python特训营-文件读写
  3. 7-2 n个非负整数的统计 简单做法
  4. element-ui——element-ui 问号提示组件的使用
  5. vue中,页面使用<keep-alive>缓存,页面切换不调用beforeDestroy和destroyed
  6. remote: XXX Incorrect username or password (access token) fatal: Authentication failed for XXX
  7. java计算机毕业设计室内游戏俱乐部系统源代码+数据库+系统+lw文档
  8. html的特质语义:微格式及其他(重点介绍其中两种)
  9. HSF + EDAS 搭建微服务项目
  10. 腾讯云TDSQL-MYSQL备份恢复实战详细截图