QT遍历QTreeView树型结构
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
QVBoxLayout *vbox = new QVBoxLayout;
QTreeView *treeView = new QTreeView;
model = new QStandardItemModel;
QPushButton *button = new QPushButton(QStringLiteral("遍历树"));
//QTreeView常用的设置
treeView->setSelectionMode(QAbstractItemView::SingleSelection);
treeView->setSelectionBehavior(QAbstractItemView::SelectRows);
treeView->setAlternatingRowColors(true);
treeView->setEditTriggers(QAbstractItemView::NoEditTriggers);
//设置标题
model->setHorizontalHeaderLabels(QStringList() << QStringLiteral("年级/班级") << QStringLiteral("姓名") << QStringLiteral("分数") << QStringLiteral("评价"));
//表头相关的设置
treeView->header()->setStretchLastSection(true);//最后一列自适应宽度
//往model里面添加数据
//一级节点只有 班级列的数据
for(int i = 0; i < 5; i++)
{
QStandardItem *item = new QStandardItem(QStringLiteral("%1年级").arg(i + 1));
model->appendRow(item);
for(int j = 0; j < 5; j++)
{
QStandardItem *item1_0 = new QStandardItem(QStringLiteral("%1班").arg(j + 1));
QStandardItem *item1_1 = new QStandardItem(QStringLiteral("Tom"));
QStandardItem *item1_2 = new QStandardItem(QStringLiteral("100"));
QStandardItem *item1_3 = new QStandardItem(QStringLiteral("差"));
item->appendRow(QList<QStandardItem*>() << item1_0 << item1_1 << item1_2 << item1_3);
}
}
treeView->setModel(model);
vbox->addWidget(treeView);
vbox->addWidget(button);
connect(button, &QPushButton::clicked, this, &Widget::slot_thebutton);
setLayout(vbox);
}
Widget::~Widget()
{
delete ui;
}
void Widget::slot_thebutton()
{
QStandardItem *rootItem = model->invisibleRootItem();
qDebug() << "rows is " << rootItem->rowCount() << "columnCount is " << rootItem->columnCount();
recursionTree(rootItem);
}
void Widget::recursionTree(QStandardItem *rootItem)
{
if(rootItem->hasChildren())
{
for(int i = 0; i < rootItem->rowCount(); i++)
{
for(int j = 0; j < rootItem->columnCount(); j++)
{
QStandardItem *item = rootItem->child(i, j);
if(item)
{
qDebug() << item->text();
if(item->hasChildren())
{
recursionTree(item);
}
}
}
}
}
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QVBoxLayout>
#include <QTreeView>
#include <QStandardItemModel>
#include <QPushButton>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
void slot_thebutton();
void recursionTree(QStandardItem *rootItem);
private:
Ui::Widget *ui;
QStandardItemModel *model;
};
#endif // WIDGET_H
注意点
1. recursionTree 递归函数看上去有点怪。如果要遍历整棵树必须要传入 model的 invisibleRootItem() 这是因为标准模型都有一个看不到的根节点。
if(item)
判断item
是否为空,是非常重要的。因为在有些情况下 item
为空是正常。如下
看起来根节点下面是班级但是班级节点的columnCount看起来是 1 但是实际上是 4。这是因为在源码中有如下代码