QTreeView做出复选框功能

 相关资料:

https://blog.csdn.net/xdw_it/article/details/80973144  

mainwindow.cpp

  1 #include "mainwindow.h"
  2 #include "ui_mainwindow.h"
  3 
  4 MainWindow::MainWindow(QWidget *parent)
  5     : QMainWindow(parent)
  6     , ui(new Ui::MainWindow)
  7 {
  8     ui->setupUi(this);
  9     setWindowTitle(QStringLiteral("QTreeView做出复选框功能"));
 10 
 11     m_publicIconMap[QStringLiteral("treeItem_Project")] = QIcon(QStringLiteral(":/new/image/image/Project.png"));
 12     m_publicIconMap[QStringLiteral("treeItem_folder")] = QIcon(QStringLiteral(":/new/image/image/folder.png"));
 13     m_publicIconMap[QStringLiteral("treeItem_folder-ansys")] = QIcon(QStringLiteral(":/new/image/image/folder-ansys.png"));
 14     m_publicIconMap[QStringLiteral("treeItem_group")] = QIcon(QStringLiteral(":/new/image/image/group.png"));
 15     m_publicIconMap[QStringLiteral("treeItem_channel")] = QIcon(QStringLiteral(":/new/image/image/channel.png"));
 16 
 17     QStandardItemModel* model = new QStandardItemModel(ui->treeView);
 18     model->setHorizontalHeaderLabels(QStringList()<<QStringLiteral("项目名")<<QStringLiteral("信息"));
 19     QStandardItem* itemProject = new QStandardItem(m_publicIconMap[QStringLiteral("treeItem_Project")],QStringLiteral("项目"));
 20     model->appendRow(itemProject);
 21     model->setItem(model->indexFromItem(itemProject).row(),1,new QStandardItem(QStringLiteral("项目信息说明")));
 22     QStandardItem* itemFolder = new QStandardItem(m_publicIconMap[QStringLiteral("treeItem_folder")],QStringLiteral("文件夹1"));
 23     itemProject->appendRow(itemFolder);
 24     itemProject->setChild(itemFolder->index().row(),1,new QStandardItem(QStringLiteral("信息说明")));
 25     itemFolder = new QStandardItem(m_publicIconMap[QStringLiteral("treeItem_folder")],QStringLiteral("文件夹2"));
 26     itemProject->appendRow(itemFolder);
 27     for(int i=0;i<5;++i)
 28     {
 29         QStandardItem* itemgroup = new QStandardItem(m_publicIconMap[QStringLiteral("treeItem_group")],QStringLiteral("组%1").arg(i+1));
 30         itemFolder->appendRow(itemgroup);
 31         for(int j=0;j<(i+1);++j)
 32         {
 33             QStandardItem* itemchannel = new QStandardItem(m_publicIconMap[QStringLiteral("treeItem_channel")],QStringLiteral("频道%1").arg(j+1));
 34             itemgroup->appendRow(itemchannel);
 35             itemgroup->setChild(itemchannel->index().row(),1,new QStandardItem(QStringLiteral("频道%1信息说明").arg(j+1)));
 36         }
 37     }
 38     itemProject->setChild(itemFolder->index().row(),1,new QStandardItem(QStringLiteral("文件夹2信息说明")));
 39     itemProject = new QStandardItem(m_publicIconMap[QStringLiteral("treeItem_Project")],QStringLiteral("项目2"));
 40     itemProject->setCheckable(true);
 41     itemProject->setTristate(true);
 42     model->appendRow(itemProject);
 43     for(int i =0;i<3;++i)
 44     {
 45         itemFolder = new QStandardItem(m_publicIconMap[QStringLiteral("treeItem_folder")],QStringLiteral("项目2文件夹%1").arg(i+1));
 46         itemFolder->setCheckable(true);
 47         itemFolder->setTristate(true);
 48         QStandardItem* itemFolderDes = new QStandardItem(m_publicIconMap[QStringLiteral("treeItem_group")],QStringLiteral("文件夹%1组").arg(i+1));
 49         itemProject->appendRow(itemFolder);
 50         itemProject->setChild(itemFolder->index().row(),1,itemFolderDes);
 51         for(int j=0;j<i+1;++j)
 52         {
 53             QStandardItem* item = new QStandardItem(m_publicIconMap[QStringLiteral("treeItem_dataItem")],QStringLiteral("项目%1").arg(j+1));
 54             item->setCheckable(true);
 55             itemFolder->appendRow(item);
 56         }
 57     }
 58     //关联项目属性改变的信号和槽
 59     connect(model,&QStandardItemModel::itemChanged,this,&::MainWindow::on_treeItemChanged);
 60     //connect(model,SIGNAL(itemChanged(QStandardItem*)),this,SLOT(treeItemChanged(QStandardItem*)));
 61     ui->treeView->setModel(model);
 62 }
 63 
 64 MainWindow::~MainWindow()
 65 {
 66     delete ui;
 67 }
 68 
 69 void MainWindow::on_treeView_clicked(const QModelIndex &index)
 70 {
 71     QString sData;
 72     QString sDir;
 73     QString sfilePath;
 74     QString stype;
 75     QString sfileName;
 76     QString sFromatStr = QStringLiteral("data:%1 
isDir:%2 
filePath:%3 
type:%4 
fileName:%5");
 77     sData = index.data().toString();
 78 //    sDir = QString::number(m_pFileModel->isDir(index));
 79 //    sfilePath = m_pFileModel->filePath(index);
 80 //    stype = m_pFileModel->type(index);
 81 //    sfileName = m_pFileModel->fileName(index);
 82 
 83     ui->textEdit->setText("");
 84     ui->textEdit->append(sFromatStr.arg(sData).arg(sDir).arg(sfilePath).arg(stype).arg(sfileName));
 85 }
 86 
 87 // brief 测量兄弟节点的情况,如果都选中返回Qt::Checked,都不选中Qt::Unchecked,不完全选中返回Qt::PartiallyChecked
 88 // param item
 89 // return 如果都选中返回Qt::Checked,都不选中Qt::Unchecked,不完全选中返回Qt::PartiallyChecked
 90 Qt::CheckState MainWindow::checkSibling(QStandardItem * item)
 91 {
 92     //先通过父节点获取兄弟节点
 93     QStandardItem * parent = item->parent();
 94     if(nullptr == parent)
 95         return item->checkState();
 96     int brotherCount = parent->rowCount();
 97     int checkedCount(0),unCheckedCount(0);
 98     Qt::CheckState state;
 99     for(int i=0;i<brotherCount;++i)
100     {
101         QStandardItem* siblingItem = parent->child(i);
102         state = siblingItem->checkState();
103         if(Qt::PartiallyChecked == state)
104             return Qt::PartiallyChecked;
105         else if(Qt::Unchecked == state)
106             ++unCheckedCount;
107         else
108             ++checkedCount;
109         if(checkedCount>0 && unCheckedCount>0)
110             return Qt::PartiallyChecked;
111     }
112     if(unCheckedCount>0)
113         return Qt::Unchecked;
114     return Qt::Checked;
115 }
116 
117 void MainWindow::on_treeItemChanged(QStandardItem * item)
118 {
119     qDebug() << "on_treeItemChanged";
120 
121     if ( item == nullptr )
122         return ;
123         if ( item->isCheckable ())
124         {
125             //如果条目是存在复选框的,那么就进行下面的操作
126             Qt::CheckState state = item->checkState(); //获取当前的选择状态
127             if (item->isTristate())
128             {
129                  //如果条目是三态的,说明可以对子目录进行全选和全不选的设置
130                 if ( state != Qt::PartiallyChecked )
131                 {
132                     //当前是选中状态,需要对其子项目进行全选
133                     treeItem_checkAllChild ( item , state == Qt::Checked ? true : false );
134                 }
135             }
136             else
137             {
138                 //说明是两态的,两态会对父级的三态有影响
139                 //判断兄弟节点的情况
140                 treeItem_CheckChildChanged(item);
141             }
142         }
143 }
144 
145 // brief 根据子节点的改变,更改父节点的选择情况
146 // param item
147 void MainWindow::treeItem_CheckChildChanged(QStandardItem * item)
148 {
149     if(nullptr == item)
150         return;
151     Qt::CheckState siblingState = checkSibling(item);
152     QStandardItem * parentItem = item->parent();
153     if(nullptr == parentItem)
154         return;
155     if(Qt::PartiallyChecked == siblingState)
156     {
157         if(parentItem->isCheckable() && parentItem->isTristate())
158             parentItem->setCheckState(Qt::PartiallyChecked);
159     }
160     else if(Qt::Checked == siblingState)
161     {
162         if(parentItem->isCheckable())
163             parentItem->setCheckState(Qt::Checked);
164     }
165     else
166     {
167         if(parentItem->isCheckable())
168             parentItem->setCheckState(Qt::Unchecked);
169     }
170     treeItem_CheckChildChanged(parentItem);
171 }
172 
173 // brief 递归设置所有的子项目为全选或全不选状态
174 // param item 当前项目
175 // param check true时为全选,false时全不选
176 void MainWindow::treeItem_checkAllChild(QStandardItem *item, bool check)
177 {
178     if(item == nullptr)
179         return;
180     int rowCount = item->rowCount();
181     for(int i=0;i<rowCount;++i)
182     {
183         QStandardItem* childItems = item->child(i);
184         treeItem_checkAllChild_recursion(childItems,check);
185     }
186     if(item->isCheckable())
187         item->setCheckState(check ? Qt::Checked : Qt::Unchecked);
188 }
189 
190 void MainWindow::treeItem_checkAllChild_recursion(QStandardItem * item,bool check)
191 {
192     if(item == nullptr)
193         return;
194     int rowCount = item->rowCount();
195     for(int i=0;i<rowCount;++i)
196     {
197         QStandardItem* childItems = item->child(i);
198         treeItem_checkAllChild_recursion(childItems,check);
199     }
200     if(item->isCheckable())
201         item->setCheckState(check ? Qt::Checked : Qt::Unchecked);
202 }
View Code
原文地址:https://www.cnblogs.com/FKdelphi/p/14116445.html