QTreeView三态checkbox代码



/*-----------------------------------

 *
 * Class PermissionTreeView
 *
*-----------------------------------*/
class PermissionTreeView : public QTreeView
{
    Q_OBJECT
public:
    explicit PermissionTreeView(QWidget *parent = 0);
    ~PermissionTreeView();
    void setModel(QStandardItemModel *model);

private:
    void treeItemCheckAllChildRecursion(QStandardItem *item, bool check);
    void treeItemCheckParentRecursion(QStandardItem *item);
    void treeItemCheckChildChanged( QStandardItem *item );
    Qt::CheckState checkSibling(QStandardItem * item);

private slots:
    void treeItemChanged( QStandardItem *item );                            //某一项状态被改变后的处理函数

private:
};


/*-----------------------------------
 *
 * Class PermissionTreeView
 *
*-----------------------------------*/
PermissionTreeView::PermissionTreeView(QWidget *parent) :
    QTreeView(parent)
{
    /*--------------------------
    *
    *--------------------------*/
    setHeaderHidden(true);
}

PermissionTreeView::~PermissionTreeView()
{

}

void PermissionTreeView::setModel(QStandardItemModel *model)
{
    connect(model, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(treeItemChanged(QStandardItem*)));

    QAbstractItemModel *aModel = qobject_cast<QAbstractItemModel *>(model);
    QTreeView::setModel(aModel);
}

void PermissionTreeView::treeItemCheckAllChildRecursion(QStandardItem *item, bool check)
{
    if(item == NULL)
        return;
    int rowCount = item->rowCount();
    for(int i = 0; i < rowCount; ++i)
    {
        QStandardItem* childItems = item->child(i);
        treeItemCheckAllChildRecursion( childItems, check );
    }
    if( item->isCheckable() )
        item->setCheckState( check ? Qt::Checked : Qt::Unchecked );
}

void PermissionTreeView::treeItemCheckParentRecursion(QStandardItem *item)
{
    Qt::CheckState status = checkSibling(item);
    QStandardItem * parent = item->parent();
    if(NULL != parent)
    {
        item->parent()->setCheckState(status);
        treeItemCheckParentRecursion(item->parent());
    }
}


void PermissionTreeView::treeItemCheckChildChanged(QStandardItem *item)
{
    if(NULL == item)
        return;
    Qt::CheckState siblingState = checkSibling(item);
    QStandardItem * parentItem = item->parent();
    if(NULL == 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);
    }
    treeItemCheckChildChanged(parentItem);
}

Qt::CheckState PermissionTreeView::checkSibling(QStandardItem *item)
{
    //先通过父节点获取兄弟节点
    QStandardItem * parent = item->parent();
    if(NULL == 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;
}

void PermissionTreeView::treeItemChanged(QStandardItem *item)
{
    if ( item == NULL )
        return ;

    //如果条目是存在复选框的,那么就进行下面的操作
    if ( item->isCheckable ())
    {
        Qt::CheckState state = item->checkState (); //获取当前的选择状态

        //如果条目是三态的,说明可以对子目录进行全选和全不选的设置
        if ( item->isTristate ())
        {
            //非半选状态
            if ( state != Qt::PartiallyChecked )
            {
                //对子目录进行操作
                treeItemCheckAllChildRecursion( item , state == Qt::Checked ? true : false );

                //对父目录进行操作
                treeItemCheckParentRecursion(item);
            }
            else
            {
            }
        }
        //说明是两态的,两态会对父级的三态有影响
        else
        {
            //判断兄弟节点的情况
//            treeItemCheckChildChanged( item );
        }
    }

}
时间: 2024-08-30 15:17:41

QTreeView三态checkbox代码的相关文章

php之三态checkbox

<div class="pnav-box" id="letter-a"> <div class="box-title"> <a class="btn-unfold" data-power="icon" data-v="close" href="javascript:;"></a> <input data-check

表单中全选或者全不选的checkbox代码

<th><input type="checkbox" id="check_all_id"></th> $(document).on('click','#check_all_id',function(){ var isChecked = $(this).prop('checked'); $(':checkbox').prop('checked', isChecked);});

JQuery对CheckBox的一些相关操作

一.通过选择器选取CheckBox: 1.给CheckBox设置一个id属性,通过id选择器选取: <input type="checkbox" name="myBox" id="chkOne" value="1" checked="checked" /> JQuery:         $("#chkOne").click(function(){}); 2.给CheckBo

[ ObjectListView ] - ListView的增强控件 - 前言 (翻译)

********************************************************************************** 原  标 题: A Much Easier to Use ListView 原文地址: https://www.codeproject.com/Articles/16009/A-Much-Easier-to-Use-ListView 翻       译: 于国栋 http://www.shannon.net.cn *********

python之路-----前端之html协议一

一.概述 1.1 什么是html语句? 超文本标记语言(Hypertext Markup Language,HTML)通过标签语言来标记要显示的网页中的各个部分.一套规则,浏览器认识的规则 浏览器按顺序渲染网页文件,然后根据标记符解释和显示内容.但需要注意的是,对于不同的浏览器,对同一标签可能会有不完全相同的解释(兼容性) 静态网页文件扩展名:.html 或 .htm 1.2 注意点 HTML 不是一种编程语言,而是一种标记语言 (markup language) HTML 使用标记标签来描述网

大三在校生的传智120天的1200小时.net(九) 关于JQuery

整理jq基础常用(过于基础别喷): 1, $('div input[name]').css('','');//获取层中有name属性的标签 $('div input[name=txtname]').css('','');//获取层中有name属性的,并且属性值为txtname的标签 $('div input[name!=txtname]').css('','');//获取层中有name属性的,并且属性值不为txtname的input标签 $('div input[name^=n]').css('

我也来说说js的事件机制

原文链接:http://www.w3cfuns.com/notes/17398/8062de2558ef495ce6cb7679f940ae5c.html 学js,不懂事件机制,基本可以说学了js,就是白学.本人看了很多js相关书籍,评价一本说讲得好不好,我主要看两块儿,一块儿是js面向对象讲得怎么样,另一块儿就是这个事件机制这块儿.面向对象按下不表,这里就详细说说事件机制.事件这个东西可以说js中核心之一.为啥如此重要,因为js是一门事件驱动的语言. 说说本文的结构.(真的好长,又不想写成一个

在WebGrid中做 批量删除操作

一般的MVC WebGrid都是在每一行中加入 Edit Detail Delete 这些Link 去对每条记录去单独操作. 稍微研究了一下总结一个 做批量删除的办法. 1. 首先是在WebGrid中加入一列CheckBox代码如下 grid.Column(header: " ", format: @<text><input class="check-box" id="chkbox" name="chkbox"

基础项目(3)三态门程序设计讲解

写在前面的话 我们所接触到的IO都是单纯的输入(input)或者输出(output)类型,而我们的一些总线协议如IIC等,要求信号为三态类型,也就是我们所说的输入输出(inout)类型.那么,本节梦翼师兄将和大家一起来探讨三态门的用法. 项目需求 设计一个三态门电路,可以实现数据的输出和总线“挂起”. 系统架构 模块功能介绍 模块名 功能描述 three_state 控制三态总线Sda是否处于挂起状态 顶层模块端口描述 端口名 端口说明 Clk 系统时钟 Rst_n 系统低电平复位 Data_b