当前位置:网站首页>Qtreeview+ custom model implementation example

Qtreeview+ custom model implementation example

2022-07-04 09:40:00 I washed my feet in Bangong Lake

QTreeView It is used to display the data of tree structure , Such as directory organization , Organizational structure, etc , Small amount of data can be used Qt Self contained Model Realization , If you have a lot of data , You need to use customized Model Realization , The following describes how to customize the implementation , Go straight to the code :

#ifndef TYPEDEF_H
#define TYPEDEF_H

#include <QVector>

// department Information 
typedef struct Department_t{
    QString name;                   //  Department name 
    int id;                         //  department id Number 
    int number;                     //  Number of departments 
    QString preOrganizationName;    //  Name of superior organization 

    Department_t()
    {
        id = 0;
        number = 0;
    }
    QVector<Department_t*> subList;
} Department;

//  Tree column number 
enum COLUMN
{
    COLUMN_NAME = 0,
    COLUMN_ID,
    COLUMN_NUM,
    COLUMN_OrganizationName
};

#endif // TYPEDEF_H

#ifndef TREEITEM_H
#define TREEITEM_H

#include <QVariant>

class TreeItem
{
public:
    enum Type
    {
        UNKNOWN = -1,
        PROVINCE,
        PERSON
    };

    explicit TreeItem(TreeItem *parent = nullptr);
    ~TreeItem();

    void addChild(TreeItem *item);
    void removeChildren();

    TreeItem *child(int row) { return _children.value(row); }
    TreeItem *parent() { return _parent; }

    int childCount() const { return _children.count(); }

    QVariant data(int column) const;

    // Set up 、 Get the data pointer stored in the node 
    void setPtr(void* p) { _ptr = p; }
    void* ptr() const { return _ptr; }

    //  Save the child nodes of the parent node , Query optimization used 
    void setRow(int row) { _row = row; }
    //  Return the number of child nodes under the parent node 
    int row() const { return _row; }

    Type getType() const { return _type; }
    void setType(const Type &value) { _type = value; }

private:
    QList<TreeItem*> _children;   //  Child node 
    TreeItem *_parent;          //  Parent node 
    Type _type;      //  The data type saved by this node 
    void* _ptr;     //  Pointer to store data 
    int _row;       //  this item The number of... In the parent node 
};

#endif // TREEITEM_H
#include "TreeItem.h"
#include "typedef.h"

TreeItem::TreeItem(TreeItem *parent)
    : _parent(parent),
      _type(UNKNOWN),
      _ptr(nullptr),
      _row(-1)
{

}

TreeItem::~TreeItem()
{
    removeChildren();
}

//  Add child nodes under this node 
void TreeItem::addChild(TreeItem *item)
{
    item->setRow(_children.size());
    _children.append(item);
}

//  Clear all child nodes 
void TreeItem::removeChildren()
{
    qDeleteAll(_children);
    _children.clear();
}

//  Get the... Of this node column Columns of data 
QVariant TreeItem::data(int column) const
{
    Department *department = (Department*)_ptr;
    switch (column) {
        case COLUMN_NAME: return department->name;
        case COLUMN_ID: return department->id;
        case COLUMN_NUM: return department->number;
        case COLUMN_OrganizationName: return department->preOrganizationName;
    default:return QVariant();
    }

    return QVariant();
}
#ifndef TREEMODEL_H
#define TREEMODEL_H
#include <QAbstractItemModel>

class TreeItem;

class TreeModel : public QAbstractItemModel
{
    Q_OBJECT
public:
    explicit TreeModel(const QStringList& headers, QObject *parent = nullptr);
    ~TreeModel() override;

    TreeItem *root();

    QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
    QVariant data(const QModelIndex &index, int role) const override;
    QModelIndex index(int row, int column, const QModelIndex &parent) const override;
    QModelIndex parent(const QModelIndex &index) const override;
    int rowCount(const QModelIndex &parent) const override;
    int columnCount(const QModelIndex &parent) const override;

private:
    TreeItem *itemFromIndex(const QModelIndex &index) const;

private:
    QStringList _headers;
    TreeItem* _rootItem;
};

#endif // TREEMODEL_H
#include "TreeModel.h"
#include "TreeItem.h"

TreeModel::TreeModel(const QStringList& headers, QObject *parent)
    : QAbstractItemModel(parent)
{
    _headers = headers;
    _rootItem = new TreeItem();
}

TreeModel::~TreeModel()
{
    delete _rootItem;
}

TreeItem *TreeModel::itemFromIndex(const QModelIndex &index) const
{
    if (index.isValid())
    {
        TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
        return item;
    }
    return _rootItem;
}

TreeItem *TreeModel::root()
{
    return _rootItem;
}

//  Get header data 
QVariant TreeModel::headerData(int section, Qt::Orientation orientation,int role) const
{
    if (orientation == Qt::Horizontal)
    {
        if(role == Qt::DisplayRole)
        {
            return _headers.at(section);
        }
    }
    return QVariant();
}

//  obtain index.row That's ok ,index.column Column data 
QVariant TreeModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    TreeItem *item = itemFromIndex(index);
    if (role == Qt::DisplayRole)
    {
        return item->data(index.column());
    }
    return QVariant();
}

//  stay parent Under the node , The first row That's ok , The first column Create index on column position 
QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const
{
    if (!hasIndex(row, column, parent))
        return QModelIndex();

    TreeItem *parentItem = itemFromIndex(parent);
    TreeItem *item = parentItem->child(row);
    if (item)
        return createIndex(row, column, item);
    else
        return QModelIndex();
}

//  establish index Parent index of 
QModelIndex TreeModel::parent(const QModelIndex &index) const
{
    if (!index.isValid())
        return QModelIndex();

    TreeItem *item = itemFromIndex(index);
    TreeItem *parentItem = item->parent();

    if (parentItem == _rootItem)
        return QModelIndex();
    return createIndex(parentItem->row(), 0, parentItem);
}

//  Get index parent How many lines are there 
int TreeModel::rowCount(const QModelIndex &parent) const
{
    if (parent.column() > 0)
        return 0;

    TreeItem* item = itemFromIndex(parent);
    return item->childCount();
}

//  Returns the index parent How many columns are there 
int TreeModel::columnCount(const QModelIndex &parent) const
{
    return _headers.size();
}
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QTreeView>
#include <QHeaderView>
#include <QFile>
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonArray>
#include "TreeModel.h"
#include "TreeItem.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    treeView = new QTreeView(this);
    treeView->setSelectionBehavior(QTreeView::SelectRows);			// Select the entire row at once 
    treeView->setSelectionMode(QTreeView::SingleSelection);         // The radio , Matching the whole line above is to select a single line at one time 
    treeView->setFocusPolicy(Qt::NoFocus);                          // Remove the dotted box when the mouse moves over the cell 
    treeView->header()->setStretchLastSection(true);                // Last column adaptive width 
    //treeView->setHeaderHidden(true);                                // Set header hide 
    setCentralWidget(treeView);

    QVector<Department*> proList = initData();
    setModel(proList);
}

MainWindow::~MainWindow()
{
    delete ui;
}

QVector<Department*>  MainWindow::initData()
{

    QFile file(":/default2.txt");
    file.open(QIODevice::ReadOnly);

    QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
    QJsonObject obj = doc.object();
    QJsonArray array = obj.value("nextLevel").toArray();
    QVector<Department*> depList;
    qDebug() << "TreeModel::setupModelDataJson==============array.size()====" << array.size() << __LINE__;
    for(int i = 0; i < array.size(); ++i)
    {
        QJsonObject subObject = array.at(i).toObject();
        QJsonArray subArray = subObject.value("nextLevel").toArray();
        Department *topDepartment = new Department();
        topDepartment->id = subObject.value("id").toInt();
        topDepartment->name = subObject.value("name").toString();
        topDepartment->number = subObject.value("nnt").toInt();
        topDepartment->preOrganizationName = subObject.value("preOrganizationName").toString();
        qDebug() << "TreeModel::setupModelDataJson==============subArray.size()====" << subArray.size() << __LINE__;
        // Level second 
        for(int i = 0; i < subArray.size(); ++i)
        {
            QJsonObject tempObj = subArray.at(i).toObject();
            Department *subDepartment = new Department();
            subDepartment->id = tempObj.value("id").toInt();
            subDepartment->name = tempObj.value("name").toString();
            subDepartment->number = tempObj.value("nnt").toInt();
            subDepartment->preOrganizationName = tempObj.value("preOrganizationName").toString();
            topDepartment->subList.append(subDepartment);
        }

        depList.append(topDepartment);
    }

    return depList;
}

void MainWindow::setModel(const QVector<Department *> &depList)
{
    QStringList headers;
    headers << QStringLiteral(" Department name ")
            << QStringLiteral(" department Id")
            << QStringLiteral(" Number of departments ")
            << QStringLiteral(" Superior department ");

    TreeModel* model = new TreeModel(headers, treeView);
    TreeItem* root = model->root();
    foreach (auto depNode, depList)
    {
        TreeItem* depItem = new TreeItem(root);
        depItem->setPtr(depNode); //  Save data pointer 
        root->addChild(depItem);

        foreach (auto subNode, depNode->subList)
        {
            TreeItem* subItem = new TreeItem(depItem);
            subItem->setPtr(subNode);    //  Save data pointer 
            depItem->addChild(subItem);
        }
    }

    treeView->setModel(model);
}

Running results :

  Reference resources :

《QTreeView+QAbstractItemModel Custom model 》: The third in the series _ Bai liyang's blog -CSDN Blog _qtreeview Customize
QTreeView Use summary 13, Customize model Example , Greatly optimize performance and memory _ Inverse maple ゛ The blog of -CSDN Blog _qtreeview usage
Qt Customize treemodel_sydnash The blog of -CSDN Blog _qt Customize treemodel

Qt Editable tree model (Tree Model) An example of _qq_21291397 The blog of -CSDN Blog _pyqt treemodel

Qt QTreeView Detailed explanation _Mr.codeee The blog of -CSDN Blog _qt treeview

QJsonObject and QString Interturn _ When the wind blows ~ Cool blog -CSDN Blog _qjsonobject turn qstring

Complete source code and test data



QTreeView+ Customize Model Implementation example -C++ Document resources -CSDN download

原网站

版权声明
本文为[I washed my feet in Bangong Lake]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/185/202207040857126549.html