1. 程式人生 > 其它 >基於Qt實現的簡單Json文字視覺化瀏覽編輯器

基於Qt實現的簡單Json文字視覺化瀏覽編輯器

主要用到的是QTreeWidget,目前實現了可以修改和儲存json檔案。

示例json片段:

{
    "array": [
        111,
        222,
        33333.001,
        "abc"
    ],
    "date": "2021-10-26"
}

執行效果圖:

程式碼:

JsonEditorMainWindow.h

#ifndef JSONEDITORMAINWINDOW_H
#define JSONEDITORMAINWINDOW_H

#include <QMainWindow>
#include <QJsonDocument>
#include 
<QJsonValue> #include <QTreeWidgetItem> QT_BEGIN_NAMESPACE namespace Ui { class JsonEditorMainWindow; } QT_END_NAMESPACE class JsonEditorMainWindow : public QMainWindow { Q_OBJECT public: JsonEditorMainWindow(QWidget *parent = nullptr); ~JsonEditorMainWindow(); private: QJsonValue string_to_jsonvalue(
const QString& text); void parse_json_value(const QJsonValue& json_value, QTreeWidgetItem* parent); void update_tree_widget_by_json(); void parse_tree_widget_value(const QTreeWidgetItem* item, QJsonArray& json_array); void parse_tree_widget_value(const QTreeWidgetItem* item, QJsonObject& json_obj);
void tree_widget_to_json(); private slots: void on_menu_action_triggered(QAction* action); void on_treeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column); private: Ui::JsonEditorMainWindow *ui; QString _current_json_filename; QJsonDocument _current_json_doc; }; #endif // JSONEDITORMAINWINDOW_H

JsonEditorMainWindow.cpp

#include "JsonEditorMainWindow.h"
#include "./ui_jsoneditormainwindow.h"
#include <QFileDialog>
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
#include <QInputDialog>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
#include <QStack>

JsonEditorMainWindow::JsonEditorMainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::JsonEditorMainWindow)
{
    ui->setupUi(this);

    ui->menu->connect(ui->menu, SIGNAL(triggered(QAction*)), this, SLOT(on_menu_action_triggered(QAction*)));
}

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

QJsonValue JsonEditorMainWindow::string_to_jsonvalue(const QString& text)
{
    if (text == tr("true"))
    {
        return QJsonValue(true);
    }
    else if (text == tr("false"))
    {
        return QJsonValue(false);
    }
    else if (text == tr("null"))
    {
        return QJsonValue();
    }
    else
    {
        if (text.size() == QVariant(text.toDouble()).toString().size())
        {
            return QJsonValue(text.toDouble());
        }
        else
        {
            return QJsonValue(text);
        }
    }
    return QJsonValue(text);
}

void JsonEditorMainWindow::parse_json_value(const QJsonValue& json_value, QTreeWidgetItem* parent)
{
    if (json_value.isArray())
    {
        QTreeWidgetItem* child = new QTreeWidgetItem(QStringList(tr("[Array]")));
        parent->addChild(child);
        auto json_array = json_value.toArray();
        for (auto idx = 0; idx < json_array.size(); ++idx)
        {
            parse_json_value(json_array[idx], child);
        }
    }
    else if (json_value.isObject())
    {
        QTreeWidgetItem* child = new QTreeWidgetItem(QStringList(tr("{Object}")));
        parent->addChild(child);
        auto json_obj = json_value.toObject();
        QStringList keys = json_obj.keys();
        for (auto idx = 0; idx < keys.size(); ++idx)
        {
            QTreeWidgetItem* next_child = new QTreeWidgetItem(QStringList(keys[idx]));
            child->addChild(next_child);
            parse_json_value(json_obj.take(keys[idx]), next_child);
        }
    }
    else if (json_value.isBool())
    {
        QTreeWidgetItem* child = new QTreeWidgetItem(QStringList(QString(json_value.toBool() ? "true" : "false")));
        parent->addChild(child);
    }
    else if (json_value.isDouble())
    {
        QTreeWidgetItem* child = new QTreeWidgetItem(QStringList(QVariant(json_value.toDouble()).toString()));
        parent->addChild(child);
    }
    else if (json_value.isString())
    {
        QTreeWidgetItem* child = new QTreeWidgetItem(QStringList(json_value.toString()));
        parent->addChild(child);
    }
    else if (json_value.isNull())
    {
        QTreeWidgetItem* child = new QTreeWidgetItem(QStringList(tr("null")));
        parent->addChild(child);
    }
    return;
}

void JsonEditorMainWindow::update_tree_widget_by_json()
{
    QJsonDocument cur_json_doc = _current_json_doc;
    if (cur_json_doc.isArray())
    {
        QTreeWidgetItem* item = new QTreeWidgetItem(QStringList(tr("#[Array]")));
        ui->treeWidget->addTopLevelItem(item);
        auto json_array = cur_json_doc.array();
        for (auto idx = 0; idx < json_array.size(); ++idx)
        {
            parse_json_value(json_array[idx], item);
        }
    }
    else if (cur_json_doc.isObject())
    {
        QTreeWidgetItem* item = new QTreeWidgetItem(QStringList(tr("#{Object}")));
        ui->treeWidget->addTopLevelItem(item);
        auto json_obj = cur_json_doc.object();
        QStringList keys = json_obj.keys();
        for (auto idx = 0; idx < keys.size(); ++idx)
        {
            QTreeWidgetItem* child = new QTreeWidgetItem(QStringList(keys[idx]));
            item->addChild(child);
            parse_json_value(json_obj.take(keys[idx]), child);
        }
    }
    else if (cur_json_doc.isEmpty())
    {
        QMessageBox::warning(this, tr("Json file empty"), tr("Json file is empty"));
    }
    else if (cur_json_doc.isNull())
    {
        QMessageBox::warning(this, tr("Json file null"), tr("Json file is null"));
    }
    return;
}

void JsonEditorMainWindow::parse_tree_widget_value(const QTreeWidgetItem* item, QJsonArray& json_array)
{
    int child_count = item->childCount();
    for (int i = 0; i < child_count; ++i)
    {
        QTreeWidgetItem* child_item = item->child(i);
        QString text = child_item->text(0);
        if (child_item->childCount() == 0)
        {
            json_array.append(string_to_jsonvalue(text));
        }
        else
        {
            if (text == tr("[Array]"))
            {
                QJsonArray ja;
                parse_tree_widget_value(child_item, ja);
                json_array.append(ja);
            }
            else if (text == tr("{Object}"))
            {
                QJsonObject jo;
                parse_tree_widget_value(child_item, jo);
                json_array.append(jo);
            }
        }
    }
    return;
}

void JsonEditorMainWindow::parse_tree_widget_value(const QTreeWidgetItem* item, QJsonObject& json_obj)
{
    int child_count = item->childCount();
    QString key = item->text(0);
    for (int i = 0; i < child_count; ++i)
    {
        QTreeWidgetItem* child_item = item->child(i);
        QString text = child_item->text(0);
        if (child_item->childCount() == 0)
        {
            json_obj[key] = string_to_jsonvalue(text);
        }
        else
        {
            key = text;
            int next_child_count = child_item->childCount();
            for (int j = 0; j < next_child_count; ++j)
            {
                QTreeWidgetItem* next_child_item = child_item->child(j);
                QString next_child_text = next_child_item->text(0);
                if (next_child_text == tr("[Array]"))
                {
                    QJsonArray ja;
                    parse_tree_widget_value(next_child_item, ja);
                    json_obj.insert(key, ja);
                }
                else if (next_child_text == tr("{Object}"))
                {
                    QJsonObject jo;
                    parse_tree_widget_value(next_child_item, jo);
                    json_obj.insert(key, jo);
                }
                else
                {
                    json_obj[key] = string_to_jsonvalue(next_child_text);
                }
            }
        }
    }
    return;
}

void JsonEditorMainWindow::tree_widget_to_json()
{
    QJsonDocument json_doc;
    QTreeWidgetItem* item = ui->treeWidget->takeTopLevelItem(0);
    if (item != nullptr)
    {
        QString text = item->text(0);
        if (text == tr("#[Array]"))
        {
            QJsonArray json_array;
            parse_tree_widget_value(item, json_array);
            json_doc.setArray(json_array);
        }
        else if (text == tr("#{Object}"))
        {
            QJsonObject json_obj;
            parse_tree_widget_value(item, json_obj);
            json_doc.setObject(json_obj);
        }
    }
    _current_json_doc.swap(json_doc);

    return;
}

void JsonEditorMainWindow::on_menu_action_triggered(QAction* action)
{
    QString action_name(action->text());
    if (action_name == tr("開啟"))
    {
        ui->treeWidget->clear();

        QString json_filename = QFileDialog::getOpenFileName(this, tr("Open file"), tr(""), tr("*.json"));
        QFile json_file(json_filename);
        if (json_file.open(QFile::ReadOnly))
        {
            _current_json_filename = json_filename;
            QTextStream text_stream(&json_file);
            QString text_data = text_stream.readAll();
            _current_json_doc = QJsonDocument::fromJson(QByteArray(text_data.toStdString().c_str()));

            update_tree_widget_by_json();
        }
        else
        {
            QMessageBox::warning(this, tr("Open failed"), tr("Can not open file"));
        }
    }
    else if (action_name == tr("儲存"))
    {
        QFile json_file(_current_json_filename);
        if (json_file.open(QFile::WriteOnly))
        {
            tree_widget_to_json();

            QTextStream text_stream(&json_file);
            text_stream << _current_json_doc.toJson();
            json_file.close();
        }
        else
        {
            QMessageBox::warning(this, tr("Save failed"), tr("Can not save file"));
        }
    }
}

void JsonEditorMainWindow::on_treeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column)
{
    QString item_text = item->text(column);
    QString text = QInputDialog::getText(this, tr("change value"), item_text, QLineEdit::Normal, item_text);
    if (!text.isEmpty() && item_text != tr("#{Object}") && item_text != tr("#[Array]") &&
            item_text != tr("{Object}") && item_text != tr("[Array]"))
    {
        item->setText(column, text);
    }
}