1.介绍
用qt的相关的几个类处理json格式的信息
json内容:
{
"root":{
"sites": [
{ "name":"菜鸟教程" , "url":"www.runoob.com" },
{ "name":"google" , "url":"www.google.com" },
{ "name":"微博" , "url":"www.weibo.com" }
]
}
}
显示效果:
2.代码
jsontreewidget.h
#ifndef JSONTREEWIDGET_H
#define JSONTREEWIDGET_H
#include <QObject>
#include <QWidget>
#include <QJsonParseError>
#include <QJsonObject>
#include <QJsonArray>
#include <QTreeWidget>
#include <QFile>
#include <QtDebug>
class JsonTreeWidget : public QTreeWidget
{
Q_OBJECT
public:
explicit JsonTreeWidget(QWidget *parent = Q_NULLPTR);
void ReadFile(QString filPath); //读json文件用
void ReadObj(QJsonObject rootJson, QTreeWidgetItem *treeItem); //递归用
void IntoValue(QJsonValue rootValue, QTreeWidgetItem *treeItem);
private:
QTreeWidget * m_TreeWgt;
};
#endif // JSONTREEWIDGET_H
jsontreewidget.cpp
#include "jsontreewidget.h"
JsonTreeWidget::JsonTreeWidget(QWidget *parent):
QTreeWidget(parent)
{
m_TreeWgt = this;
}
void JsonTreeWidget::ReadFile(QString filPath)
{
QFile file(filPath);
if(!file.open(QIODevice::ReadOnly)) return;
QByteArray allJson = file.readAll();//全部内容
QJsonParseError jsonErr;
QJsonDocument jsonDoc(QJsonDocument::fromJson(allJson,&jsonErr));
if(jsonErr.error != QJsonParseError::NoError)
{
qDebug()<<jsonErr.errorString();
return ;
}
QJsonObject rootobj = jsonDoc.object();
m_TreeWgt->clear();//清除旧的内容
//新建顶层结点
QTreeWidgetItem *top = new QTreeWidgetItem( m_TreeWgt->topLevelItem(0),QStringList (QString("top")) );
m_TreeWgt->addTopLevelItem(top);
//递归进去,直到rootobj是个empty object
ReadObj(rootobj,m_TreeWgt->topLevelItem(0));
}
//第一层专用
void JsonTreeWidget::ReadObj(QJsonObject rootJson,QTreeWidgetItem* treeItem){
QStringList li = rootJson.keys();//下一层的判断条件
//不是叶子节点,继续层级递归
for (int i=0; i < li.size();i++) {
QJsonValue tempVal = rootJson.value(li.at((i)));
QString str = li.at(i);
QTreeWidgetItem *t = new QTreeWidgetItem;
t->setText(0,str);
treeItem->addChild(t);
//递归进去
IntoValue(tempVal,t);
}
}
void JsonTreeWidget::IntoValue(QJsonValue rootValue,QTreeWidgetItem* treeItem){
QStringList li = rootValue.toObject().keys();//下一层的判断条件
//是叶子节点了
if(li.isEmpty()){
QString str;
QJsonValue qj = rootValue;
qDebug()<<qj.type();
//是单个元素
if(QJsonValue::String == qj.type()){
str = qj.toString();
QTreeWidgetItem *t = new QTreeWidgetItem;
t->setText(0,str);
treeItem->addChild(t);
}
//是数组元素,遍历
else if(QJsonValue::Array == qj.type())
{
QJsonArray var = qj.toArray();
for (int i=0;i<var.size();i++) {
IntoValue(var.at(i) , treeItem);
}
}
return;
}
//不是叶子节点,继续层级递归
for (int i=0; i < li.size();i++) {
QJsonValue tempVal = rootValue.toObject().value(li.at((i)));
QString str = li.at(i);
QTreeWidgetItem *t = new QTreeWidgetItem;
t->setText(0,str);
treeItem->addChild(t);
//递归进去
IntoValue(tempVal,t);
}
}
3.使用方法
由于是继承QTreeWidget而创建的类,建议使用“提升为”功能
1.拉出一个 TreeWidget
2.右键这个TreeWidget,点击“提升为”
3.在提升为对话框中在“提升的类名称”中输入这个类名(JsonTreeWidget)
点完“添加”,再点“提升”
这样在右侧边框中的类名就会改变为提升的类,ui指针也可以调这个类里的函数了。
4.比如点击按钮,读取json文件并显示树状图
这是mainwindow.cpp,我只添加了一个头文集和一个按钮触发这个treeWidget的ReadFile函数。
“2.txt”里就是开头的json内容,放在与exe同级目录下即完成。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "jsontreewidget.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
ui->treeWidget->ReadFile("2.txt");
}