当前位置:网站首页>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 QTreeView Detailed explanation _Mr.codeee The blog of -CSDN Blog _qt treeview
Complete source code and test data
QTreeView+ Customize Model Implementation example -C++ Document resources -CSDN download
边栏推荐
- Kubernetes CNI 插件之Fabric
- The 14th five year plan and investment risk analysis report of China's hydrogen fluoride industry 2022 ~ 2028
- Rules for using init in golang
- 百度研发三面惨遭滑铁卢:面试官一套组合拳让我当场懵逼
- 2022-2028 global special starch industry research and trend analysis report
- 2022-2028 global visual quality analyzer industry research and trend analysis report
- Explanation of closures in golang
- 2022-2028 global protein confectionery industry research and trend analysis report
- Are there any principal guaranteed financial products in 2022?
- 26. Delete duplicates in the ordered array (fast and slow pointer de duplication)
猜你喜欢
el-table单选并隐藏全选框
Reload CUDA and cudnn (for tensorflow and pytorch) [personal sorting summary]
C语言指针面试题——第二弹
C语言指针经典面试题——第一弹
libmysqlclient.so.20: cannot open shared object file: No such file or directory
Regular expression (I)
How do microservices aggregate API documents? This wave of show~
Hands on deep learning (35) -- text preprocessing (NLP)
2022-2028 global probiotics industry research and trend analysis report
QTreeView+自定义Model实现示例
随机推荐
MySQL foundation 02 - installing MySQL in non docker version
How to write unit test cases
UML sequence diagram [easy to understand]
Write a jison parser from scratch (5/10): a brief introduction to the working principle of jison parser syntax
"How to connect the Internet" reading notes - FTTH
Tkinter Huarong Road 4x4 tutorial II
After unplugging the network cable, does the original TCP connection still exist?
pcl::fromROSMsg报警告Failed to find match for field ‘intensity‘.
Write a jison parser from scratch (6/10): parse, not define syntax
Implementing expired localstorage cache with lazy deletion and scheduled deletion
Hands on deep learning (34) -- sequence model
Pueue data migration from '0.4.0' to '0.5.0' versions
Reading notes on how to connect the network - hubs, routers and routers (III)
技术管理进阶——如何设计并跟进不同层级同学的绩效
Reload CUDA and cudnn (for tensorflow and pytorch) [personal sorting summary]
2022-2028 global protein confectionery industry research and trend analysis report
华为联机对战如何提升玩家匹配成功几率
Investment analysis and prospect prediction report of global and Chinese high purity tin oxide Market Ⓞ 2022 ~ 2027
Get the source code in the mask with the help of shims
xxl-job惊艳的设计,怎能叫人不爱