QTreeView使用模

2019-04-13 14:25发布

转载自:http://blog.csdn.net/czyt1988/article/details/18996407?utm_source=tuicool 关键代码: #include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); m_publicIconMap[TREE_ITEM_ICON_Project] = QIcon(QStringLiteral(":/treeIcon/res_treeItemIcon/Project.png")); m_publicIconMap[TREE_ITEM_ICON_folder] = QIcon(QStringLiteral(":/treeIcon/res_treeItemIcon/folder.png")); m_publicIconMap[TREE_ITEM_ICON_folderAnsys] = QIcon(QStringLiteral(":/treeIcon/res_treeItemIcon/folder-ansys.png")); m_publicIconMap[TREE_ITEM_ICON_TdmsGroup] = QIcon(QStringLiteral(":/treeIcon/res_treeItemIcon/group.png")); m_publicIconMap[TREE_ITEM_ICON_TdmsChannel] = QIcon(QStringLiteral(":/treeIcon/res_treeItemIcon/channel.png")); m_publicIconMap[TREE_ITEM_ICON_folderOriginal] = QIcon(QStringLiteral(":/treeIcon/res_treeItemIcon/folder_original.png")); m_publicIconMap[TREE_ITEM_ICON_DataItem] = QIcon(QStringLiteral(":/treeIcon/res_treeItemIcon/dataItem.png")); initTree(); } Widget::~Widget() { delete ui; } void Widget::initTree() { QStandardItemModel* model = new QStandardItemModel(ui->treeView); model->setHorizontalHeaderLabels(QStringList()<appendRow(itemProject); model->setItem(model->indexFromItem(itemProject).row(),1,new QStandardItem(QStringLiteral("项目信息说明"))); QStandardItem* itemFolder = new QStandardItem(m_publicIconMap[QStringLiteral("treeItem_folder")],QStringLiteral("文件夹1")); itemProject->appendRow(itemFolder); itemProject->setChild(itemFolder->index().row(),1,new QStandardItem(QStringLiteral("信息说明"))); itemFolder = new QStandardItem(m_publicIconMap[QStringLiteral("treeItem_folder")],QStringLiteral("文件夹2")); itemProject->appendRow(itemFolder); for(int i=0;i<5;++i){ QStandardItem* itemgroup = new QStandardItem(m_publicIconMap[QStringLiteral("treeItem_group")],QStringLiteral("组%1").arg(i+1)); itemFolder->appendRow(itemgroup); for(int j=0;j<(i+1);++j){ QStandardItem* itemchannel = new QStandardItem(m_publicIconMap[QStringLiteral("treeItem_channel")],QStringLiteral("频道%1").arg(j+1)); itemgroup->appendRow(itemchannel); itemgroup->setChild(itemchannel->index().row(),1,new QStandardItem(QStringLiteral("频道%1信息说明").arg(j+1))); } } itemProject->setChild(itemFolder->index().row(),1,new QStandardItem(QStringLiteral("文件夹2信息说明"))); itemProject = new QStandardItem(m_publicIconMap[QStringLiteral("treeItem_Project")],QStringLiteral("项目2")); model->appendRow(itemProject); for(int i =0;i<3;++i) { itemFolder = new QStandardItem(m_publicIconMap[QStringLiteral("treeItem_folder")],QStringLiteral("项目2文件夹%1").arg(i+1)); itemFolder->setCheckable(true); itemFolder->setTristate(true); QStandardItem* itemFolderDes = new QStandardItem(m_publicIconMap[QStringLiteral("treeItem_group")],QStringLiteral("文件夹%1组").arg(i+1)); itemProject->appendRow(itemFolder); itemProject->setChild(itemFolder->index().row(),1,itemFolderDes); for(int j=0;jsetCheckable(true); itemFolder->appendRow(item); } } itemProject = new QStandardItem(m_publicIconMap[QStringLiteral("treeItem_Project")],QStringLiteral("项目3")); model->appendRow(itemProject); for(int i =0;i<3;++i) { itemFolder = new QStandardItem(m_publicIconMap[QStringLiteral("treeItem_folder")],QStringLiteral("项目3文件夹%1").arg(i+1)); itemFolder->setCheckable(true); itemFolder->setTristate(true); QStandardItem* itemFolderDes = new QStandardItem(m_publicIconMap[QStringLiteral("treeItem_group")],QStringLiteral("文件夹%1组").arg(i+1)); itemProject->appendRow(itemFolder); itemProject->setChild(itemFolder->index().row(),1,itemFolderDes); for(int j=0;jsetCheckable(true); itemFolder->appendRow(item); } } //关联项目属性改变的信号和槽 connect(model,&QStandardItemModel::itemChanged,this,&Widget::treeItemChanged); ui->treeView->setModel(model); } void Widget::on_pushButton_clicked() { QStandardItemModel* model = static_cast(ui->treeView->model()); QModelIndex index = ui->treeView->currentIndex(); QStandardItem* item = model->itemFromIndex(index); ui->label->setText(QStringLiteral("当前选中:%1 row:%2,column:%3 最左边节点:%4").arg(item->text()) .arg(index.row()).arg(index.column()) .arg(index.sibling(index.row(),0).data().toString())); } /// /// rief 获取根部节点,即从属关系的可显示最上级,与invisibleRootItem不同 /// param item /// eturn /// QStandardItem* Widget::getTopParent(QStandardItem* item) { QStandardItem* secondItem = item; while(item->parent()!= 0) { secondItem = item->parent(); item = secondItem; } if(secondItem->index().column() != 0) { QStandardItemModel* model = static_cast(ui->treeView->model()); secondItem = model->itemFromIndex(secondItem->index().sibling(secondItem->index().row(),0)); } return secondItem; } QModelIndex Widget::getTopParent(QModelIndex itemIndex) { QModelIndex secondItem = itemIndex; while(itemIndex.parent().isValid()) { secondItem = itemIndex.parent(); itemIndex = secondItem; } if(secondItem.column() != 0) { secondItem = secondItem.sibling(secondItem.row(),0); } return secondItem; } void Widget::on_pushButton_2_clicked() { QStandardItemModel* model = static_cast(ui->treeView->model()); QModelIndex currentIndex = ui->treeView->currentIndex(); QStandardItem* currentItem = model->itemFromIndex(currentIndex); ui->label_2->setText("顶层节点是:"+getTopParent(currentItem)->text()); } void Widget::on_treeView_clicked(const QModelIndex &index) { QString str; str += QStringLiteral("当前选中:%1 row:%2,column:%3 ").arg(index.data().toString()) .arg(index.row()).arg(index.column()); str += QStringLiteral("父级:%1 ").arg(index.parent().data().toString()); //兄弟节点测试 QString name,info; if(index.column() == 0) { name = index.data().toString(); info = index.sibling(index.row(),1).data().toString(); } else { name = index.sibling(index.row(),0).data().toString(); info = index.data().toString(); } str += QStringLiteral("名称:%1 信息:%2 ").arg(name).arg(info); //寻找顶层 QString top = getTopParent(index).data().toString(); str += QStringLiteral("顶层节点名:%1 ").arg(top); ui->label_realTime->setText(str); } void Widget::on_pushButton_3_clicked() { QStandardItemModel* model = static_cast(ui->treeView->model()); /**invisibleRootItem()是获取model的根项(指绝对根项),根项不可见,所以前面有个invisible**/ ui->label_3->setText(QStringLiteral("model不可见根项下子Item的数目:%1").arg(model->invisibleRootItem()->rowCount())); } void Widget::treeItemChanged(QStandardItem * item) { if(item == nullptr) return; if(item->isCheckable()) { //如果条目是存在复选框的,那么就进行下面的操作 Qt::CheckState state = item->checkState();//获取当前的选择状态 if(item->isTristate()) { //如果条目是三态的,说明可以对子目录进行全选和全不选的设置 if(state != Qt::PartiallyChecked) { //当前是选中状态,需要对其子项目进行全选 treeItem_checkAllChild(item,state == Qt::Checked ? true : false); } } else { //说明是两态的,两态会对父级的三态有影响 //判断兄弟节点的情况 treeItem_CheckChildChanged(item); } } } /// /// rief 递归设置所有的子项目为全选或全不选状态 /// param item 当前项目 /// param check true时为全选,false时全不选 /// void Widget::treeItem_checkAllChild(QStandardItem * item, bool check) { if(item == nullptr) return; int rowCount = item->rowCount(); for(int i=0;ichild(i); treeItem_checkAllChild_recursion(childItems,check); } if(item->isCheckable()) item->setCheckState(check ? Qt::Checked : Qt::Unchecked); } void Widget::treeItem_checkAllChild_recursion(QStandardItem * item,bool check) { if(item == nullptr) return; int rowCount = item->rowCount(); for(int i=0;ichild(i); treeItem_checkAllChild_recursion(childItems,check); } if(item->isCheckable()) item->setCheckState(check ? Qt::Checked : Qt::Unchecked); } /// /// rief 测量兄弟节点的情况,如果都选中返回Qt::Checked,都不选中Qt::Unchecked,不完全选中返回Qt::PartiallyChecked /// param item /// eturn 如果都选中返回Qt::Checked,都不选中Qt::Unchecked,不完全选中返回Qt::PartiallyChecked /// Qt::CheckState Widget::checkSibling(QStandardItem * item) { //先通过父节点获取兄弟节点 QStandardItem * parent = item->parent(); if(nullptr == parent) return item->checkState(); int brotherCount = parent->rowCount(); int checkedCount(0),unCheckedCount(0); Qt::CheckState state; for(int i=0;ichild(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; } /// /// rief 根据子节点的改变,更改父节点的选择情况 /// param item /// void Widget::treeItem_CheckChildChanged(QStandardItem * item) { if(nullptr == item) return; Qt::CheckState siblingState = checkSibling(item); QStandardItem * parentItem = item->parent(); if(nullptr == 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); } treeItem_CheckChildChanged(parentItem); }
运行测试截图: