QTreeView的按钮选择功能,主要是利用void QStandardItem::setCheckable(bool checkable)这个函数实现的,先给大家看效果图:
下面直接看代码:
#include "widget.h"
#include "ui_widget.h"
#include <QStringListModel>
#include <QTreeView>
#include <QList>
#include <QCheckBox>
#include <QModelIndex>
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
Process();
Change();
}
void Widget::Process()
{
model = new QStandardItemModel(ui->treeView);
QStringList tableLabels = QString("number, name").simplified().split(",");
model->setHorizontalHeaderLabels(tableLabels);
ui->treeView->setModel(model);
for(int i = 0; i < 3; i++)
{
QStandardItem *all_item_num =new QStandardItem(QString::number(i + 1));
all_item_num->setEditable(false);
all_item_num->setCheckable(true);
model->setItem(i, 0, all_item_num);
model->setItem(i, 1, new QStandardItem("first"));
//插入数据
for(int j = 0; j < 5; ++j)
{
QStandardItem *singal_item_num = new QStandardItem(QString::number(j + 1));
singal_item_num->setEditable(false);
singal_item_num->setCheckable(true);
model->item(i, 0)->setChild(j, 0, singal_item_num);
model->item(i, 0)->setChild(j, 1, new QStandardItem("second"));
}
}
ui->treeView->setModel(model);
}
void Widget::Change()
{
connect(model, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(onItemChanged(QStandardItem*)));
//鼠标选中的item
connect(ui->treeView, SIGNAL(clicked(QModelIndex)), this, SLOT(getItemIndex(QModelIndex)));
}
void Widget::onItemChanged(QStandardItem *item)
{
if (item == nullptr)
return;
if(item->isCheckable())
{
Qt::CheckState state = item->checkState(); //获取当前状态
if(item->hasChildren())
checkAllChild(item, state);
else
checkChildChanged(item);
}
getSelectNode(); //打印全部选中的
}
void Widget::checkChildChanged(QStandardItem* item)
{
if (item == nullptr)
return;
Qt::CheckState siblingState = checkSibling(item);
//qDebug() << siblingState;
QStandardItem* parentItem = item->parent();
if(parentItem == nullptr)
return;
if(parentItem->checkState() == Qt::Checked)
{
item->setCheckState(Qt::Checked);
return;
}
if (siblingState == Qt::PartiallyChecked)
{
if(parentItem->isCheckable() && parentItem->isTristate())
{
parentItem->setCheckState(Qt::Unchecked);
}
}
else if(siblingState == Qt::Checked)
{
if(parentItem->isCheckable())
parentItem->setCheckState(Qt::Checked);
}
if (siblingState == Qt::Unchecked)
{
if(parentItem->isCheckable())
parentItem->setCheckState(Qt::Unchecked);
}
}
Qt::CheckState Widget::checkSibling(QStandardItem* item)
{
//先通过父节点获取兄弟节点
QStandardItem* parent = item->parent();
if(parent == nullptr)
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 Widget::checkAllChild(QStandardItem* item, bool check)
{
if(item == nullptr)
return;
int rowCount = item->rowCount();
if (check == false)
{
for(int i = 0; i < rowCount; ++i)
item->child(i)->setCheckState(Qt::Unchecked);
}
else{
for(int i = 0; i < rowCount; ++i)
item->child(i)->setCheckState(Qt::Checked);
}
}
void Widget::getSelectNode()
{
for(int i = 0; i < model->rowCount(); i++)
GetItem(model->item(i));
}
void Widget::GetItem(QStandardItem *item)
{
if(item->hasChildren())
{
for(int i = 0; i < item->rowCount(); ++i)
{
QStandardItem* childitem = item->child(i);
if(childitem->checkState() == Qt::Checked)
{
QModelIndex modelIndex = childitem->index();
modelIndex = modelIndex.sibling(modelIndex.row(), 1); //第二个元素
QString data = ui->treeView->model()->itemData(modelIndex).values()[0].toString();
}
GetItem(childitem);
}
}
}
//打印选中的元素
void Widget::getItemIndex(QModelIndex modeIndex)
{
ui->treeView->resizeColumnToContents(modeIndex.row());
QString selectedDate = ui->treeView->model()->itemData(modeIndex).values()[0].toString();
qDebug() << "selectedDate = " << selectedDate;
}
Widget::~Widget()
{
delete ui;
}