QTreeWidget 将json某字段的value转成树

比如将 图书类的json数据转换成tree结构,或者公司的组织架构。json数据小的适合很稳,如果大些性能估计就不太行了,如果有好的思路欢迎补充,我也学习下

效果

在这里插入图片描述
在这里插入图片描述

测试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();
}
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值