效果
测试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_OBJECTpublic: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相同的itemvoid 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);}// 递归展开指定的节点的parentvoid 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();}

