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

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

功能

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

实现

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图的效果。

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

鸣谢:
https://blog.csdn.net/xiaosha00000/article/details/80897210

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. 精心推荐10个高质量的网站,打开新世界的大门
  2. 走在技术前沿,今年最火的top5 +Java开源项目
  3. 以不同的维度去看待问题
  4. 复杂update_Python 代码判断逻辑太复杂?这里有几条最佳实践和技巧
  5. ASP.NET温故而知新学习系列之ASP.NET多线程编程—.NET下的多线程编程应用程序域(七)...
  6. Django(part32)--一对一映射
  7. Linux驱动如何在不同版本上快速迭代升级
  8. 【OS学习笔记】二十 保护模式六:保户模式下操作系统内核如何加载用户程序并运行 对应的汇编代码之主引导扇区程序
  9. HBase 数据迁移
  10. objective-c 中的关联介绍
  11. [2014-12-30]如何动态构造Lambda表达式(动态构造Lambda查询条件表达式)
  12. 2022微服务面试题 最新50道题(含答案解析)
  13. 24个基本指标精粹讲解(22)--ADR
  14. slot的使用方法详解
  15. html超链接调用php,html网页超链接怎么做
  16. 互联网-2互联网思维特点和理念
  17. 云服务器惠普版_惠普被评为中国私有云解决方案领导厂商
  18. Java初学者快速上手之实战“套路”
  19. 【剑指offter】重建二叉树
  20. android 键盘按下事件,Android虚拟键盘上下左右键按下和弹起的响应事件

热门文章

  1. 盘点一下 Java创建对象的几种方式(7大种)全面版
  2. 32位Oracle客户端的下载及64位Windows下的安装
  3. android 手机获取外置SD卡路径
  4. Linux操作系统 系统界面设计
  5. js table 生成序号_el-table树形表格表单验证(列表生成序号)
  6. 三星N148上网本上安装windows 2000
  7. almost unreal歌词翻译_LOVE PSYCHEDELICO
  8. linux的yum安装目录,Linux如何查看YUM的安装目录
  9. (转)Android状态栏微技巧,带你真正理解沉浸式模式
  10. CGLIB中BeanCopier源码实现