效果
测试json
{
"data": [{
"id": "1",
"parentId": "0",
"text": "编程技术",
"leaf": false,
"children": [{
"id": "python",
"parentId": "null",
"text": "python cookbook0",
"leaf": false,
"children": [{
"id": "1-1-1",
"parentId": "1-1",
"text": "python cookbook1",
"leaf": false,
"children": [{
"id": "1-1-1-1",
"parentId": "1-1-1",
"text": "python cookbook11",
"leaf": true,
"children": []
}]
}, {
"id": "1-1-2",
"parentId": "python cookbook2",
"text": "123",
"leaf": true,
"children": []
}]
}, {
"id": "1-2",
"parentId": "null",
"text": "C++",
"leaf": false,
"children": [{
"id": "1-2-1",
"parentId": "1-2",
"text": "c++ prime",
"leaf": true,
"children": []
}]
}]
}]
}
头文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
class QTreeWidget;
class QLineEdit;
class QVBoxLayout;
class QTreeWidgetItem;
class Widget : public QWidget {
Q_OBJECT
public:
Widget(QWidget* parent = nullptr);
~Widget();
private:
void initWidget();
void initConnection();
// 解析json并将指定字段添加到树节点
void parseJsonRoot();
void parseObject(const QJsonObject& obj, QTreeWidgetItem* itemNode);
void parseArray(const QJsonArray& arr, QTreeWidgetItem* itemNode);
// 树节点查找功能
void findItem(const QString& text);
void parentExpand(QTreeWidgetItem* item);
private:
QLineEdit* lineEdit;
QTreeWidget* treeWidget;
QVBoxLayout* vLayout;
};
#endif // WIDGET_H
实现
#include "widget.h"
#include <QByteArray>
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QLineEdit>
#include <QTimer>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QVBoxLayout>
Widget::Widget(QWidget* parent)
: QWidget(parent)
{
initWidget();
initConnection();
parseJsonRoot();
}
Widget::~Widget()
{
}
void Widget::initWidget()
{
this->setWindowTitle(tr("Json数据字段值转树节点及搜索"));
this->setMinimumSize(QSize(300, 400));
vLayout = new QVBoxLayout(this);
lineEdit = new QLineEdit();
lineEdit->setPlaceholderText(tr("搜索..."));
treeWidget = new QTreeWidget();
treeWidget->setHeaderHidden(true);
vLayout->addWidget(lineEdit);
vLayout->addWidget(treeWidget);
}
void Widget::initConnection()
{
connect(lineEdit, &QLineEdit::textChanged, this, &Widget::findItem);
}
void Widget::parseJsonRoot()
{
QFile file("F:\\projectCode_yhw\\untitled5\\demo.json");
file.open(QFile::ReadOnly);
QByteArray m_jsonArray = file.readAll();
QJsonParseError jsonError;
QJsonObject jsonObject;
QJsonDocument document = QJsonDocument::fromJson(m_jsonArray, &jsonError);
if (!(document.isNull() || jsonError.error != QJsonParseError::NoError)) {
jsonObject = document.object();
}
QJsonValue value = jsonObject.value("data");
if (!value.isArray()) {
return;
}
QJsonArray array = value.toArray();
int nSize = array.size();
for (int i = 0; i < nSize; i++) {
QJsonObject object = array.at(i).toObject();
if (!(object.contains("text") && object.contains("children"))) {
return;
}
QString itemText = object.value("text").toString();
QJsonArray itemChild = object.value("children").toArray();
QTreeWidgetItem* itemRoot = new QTreeWidgetItem(treeWidget, QStringList(itemText));
treeWidget->addTopLevelItem(itemRoot);
if (itemChild.size() != 0) {
parseArray(itemChild, itemRoot);
}
}
}
/**
* @brief 解析json object, 如果child对应的value为数组,则交给parseArray处理
* @param obj json object对象
* @param itemNode 树节点
*/
void Widget::parseObject(const QJsonObject& obj, QTreeWidgetItem* itemNode)
{
if (obj.contains("text") && obj.contains("children")) {
QString itemText = obj.value("text").toString();
QJsonArray itemChild = obj.value("children").toArray();
// 添加子节点
QTreeWidgetItem* item = new QTreeWidgetItem(itemNode, QStringList(itemText));
itemNode->addChild(item);
if (itemChild.size() != 0) {
parseArray(itemChild, item);
}
}
}
/**
* @brief AddVistors::parseArray
* 解析数组, 将数组的每一个值交给ParseObject()函数处理
* @param arr json数组
* @param itemNode 树节点
*/
void Widget::parseArray(const QJsonArray& arr, QTreeWidgetItem* itemNode)
{
int size = arr.size();
for (int i = 0; i < size; i++) {
QJsonObject obj = arr.at(i).toObject();
parseObject(obj, itemNode);
}
}
// 查找与text相同的item
void Widget::findItem(const QString& text)
{
treeWidget->collapseAll();
if (text.isEmpty()) {
QTreeWidgetItemIterator it(treeWidget);
while (*it) {
(*it)->setForeground(0, Qt::black);
it++;
}
return;
}
if (!treeWidget->topLevelItemCount()) {
return;
}
QTreeWidgetItemIterator it(treeWidget);
while (*it) {
this->setCursor(Qt::WaitCursor);
QString str = (*it)->text(0);
if (-1 != str.indexOf(text)) {
QTreeWidgetItem* pItem = (*it)->parent();
if (pItem != nullptr) {
bool isExpanded = pItem->isExpanded();
if (!isExpanded) {
treeWidget->expandItem(pItem);
}
}
(*it)->setForeground(0, Qt::red);
parentExpand(*it);
} else {
(*it)->setForeground(0, Qt::black);
}
it++;
}
this->setCursor(Qt::ArrowCursor);
}
// 递归展开指定的节点的parent
void Widget::parentExpand(QTreeWidgetItem* item)
{
if (item->parent() != nullptr) {
QTreeWidgetItem* pItem = item->parent();
if (!pItem->isExpanded()) {
pItem->setExpanded(true);
}
parentExpand(pItem);
}
}
main函数
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}