/*-----------------------------------
*
* 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 );
}
}
}