QJsonDocument类提供了读写JSON文档的方式,我们可以通过该类的方法QJsonDocument::fromJson()将一个JSON文档转换成QJsonDocument类,或者通过QJsonDocument::toJson()和QJsonDocument::toBinaryData()函数将一个QJsonDocument类转换为QByteArray,这样我们就可以很轻松地将其写入文件。
QJsonArray封装了JSON中的数组。
QJsonObject封装了JSON中的对象。
QJsonValue封装了JSON中的值。
QJsonParseError 用于报告JSON解析中的错误类型。
1.简单写json
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[]) {
// 以读写方式打开主目录下的1.json文件,若该文件不存在则会自动创建
QFile file(QDir::homePath() + "/1.json");
if(!file.open(QIODevice::ReadWrite)) {
qDebug() << "File open error";
} else {
qDebug() <<"File open!";
}
// 使用QJsonObject对象插入键值对。
QJsonObject jsonObject;
jsonObject.insert("name", "tom");
jsonObject.insert("age", "18");
jsonObject.insert("time", QDateTime::currentDateTime().toString());
// 使用QJsonDocument设置该json对象
QJsonDocument jsonDoc;
jsonDoc.setObject(jsonObject);
// 将json以文本形式写入文件并关闭文件。
file.write(jsonDoc.toJson());
file.close();
qDebug() << "Write to file";
return 0;
}
2.上面QJsonObject写入是无序的键值对,若要有序则可以使用QJsonArray
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[]) {
// 以读写方式打开主目录下的1.json文件,若该文件不存在则会自动创建
QFile file(QDir::homePath() + "/1.json");
if(!file.open(QIODevice::ReadWrite)) {
qDebug() << "File open error";
} else {
qDebug() <<"File open!";
}
// 清空文件中的原有内容
file.resize(0);
// 使用QJsonArray添加值,并写入文件
QJsonArray jsonArray;
jsonArray.append("name");
jsonArray.append(18);
jsonArray.append(QDateTime::currentDateTime().toString());
QJsonDocument jsonDoc;
jsonDoc.setArray(jsonArray);
file.write(jsonDoc.toJson());
file.close();
qDebug() << "Write to file";
return 0;
}
3.综合使用
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[]) {
// 以读写方式打开主目录下的1.json文件,若该文件不存在则会自动创建
QFile file(QDir::homePath() + "/1.json");
if(!file.open(QIODevice::ReadWrite)) {
qDebug() << "File open error";
} else {
qDebug() <<"File open!";
}
// 清空文件中的原有内容
file.resize(0);
// 使用QJsonArray添加值,并写入文件
QJsonArray jsonArray;
for(int i = 0; i < 3; i++) {
QJsonObject jsonObject;
jsonObject.insert("name", QString::number(i+1));
jsonObject.insert("age", i+18);
jsonObject.insert("time", QDateTime::currentDateTime().toString());
jsonArray.append(jsonObject);
QThread::sleep(2);
}
QJsonObject jsonObject;
jsonObject.insert("number", jsonArray.size());
jsonArray.append(jsonObject);
QJsonDocument jsonDoc;
jsonDoc.setArray(jsonArray);
file.write(jsonDoc.toJson());
file.close();
qDebug() << "Write to file";
return 0;
}
4.读取
json文件:
{
"first fruit":
{
"describe":"an apple",
"icon":"appleIcon",
"name":"apple"
},
"second fruit":
{
"describe":"an orange",
"icon":"orangeIcon",
"name":"orange"
},
"three fruit array":
[
"eat 0",
"eat 1",
"eat 2",
"eat 3",
"eat 4"
]
}
读取代码:
//打开文件
QFile loadFile("D:\\1.json");
if(!loadFile.open(QIODevice::ReadOnly))
{
qDebug() << "could't open projects json";
return;
}
//读取文件内容
QByteArray allData = loadFile.readAll();
loadFile.close();
//以json格式读取内容到JsonDoc
QJsonParseError jsonError;
QJsonDocument jsonDoc(QJsonDocument::fromJson(allData, &jsonError));
if(jsonError.error != QJsonParseError::NoError)
{
qDebug() << "json error!" << jsonError.errorString();
return;
}
//创建jsonObject
QJsonObject rootObj = jsonDoc.object();
QStringList keys = rootObj.keys();
for(int i = 0; i < keys.size(); i++)
{
qDebug() << "key" << i << " is:" << keys.at(i);
}
//因为是预先定义好的JSON数据格式,所以这里可以这样读取
if(rootObj.contains("first fruit"))
{
QJsonObject subObj = rootObj.value("first fruit").toObject();
qDebug() << "describe is:" << subObj["describe"].toString();
qDebug() << "icon is:" << subObj["icon"].toString();
qDebug() << "name is:" << subObj["name"].toString();
}
if(rootObj.contains("second fruit"))
{
QJsonObject subObj = rootObj.value("second fruit").toObject();
qDebug() << "describe is:" << subObj.value("describe").toString();
qDebug() << "icon is:" << subObj.value("icon").toString();
qDebug() << "name is:" << subObj.value("name").toString();
}
if(rootObj.contains("three fruit array"))
{
QJsonArray subArray = rootObj.value("three fruit array").toArray();
for(int i = 0; i< subArray.size(); i++)
{
qDebug() << i<<" value is:" << subArray.at(i).toString();
}
}
json文件:
{
//头部
"header":
{
"mapType":"2D-Map",
"mapName":"2",
"minPos":{"x":-5.132,"y":-0.158},
"maxPos":{"x":18.256,"y":10.86},
"resolution":0.02,
"version":"1.0.6"
},
//普通点集合
"normalPosList":
[
{"x":-0.006,"y":8.199},
{"x":-0.006,"y":8.219},
{"x":-0.007,"y":8.119},
//...
],
//高级点集合
"advancedPointList":
[
{
"className":"LandMark",
"instanceName":"LM1",
"pos":{"x":16.344,"y":6.621},
"property":
[
{"key":"spin","type":"bool","value":"ZmFsc2U=","boolValue":false}
]
},
{
"className":"LandMark",
"instanceName":"LM2",
"pos":{"x":3.693,"y":6.621},
"dir":-3.1415926535897931,
"property":[{"key":"spin","type":"bool","value":"ZmFsc2U=","boolValue":false}]
}
],
//曲线集合
"advancedCurveList":
[
{
"className":"BezierPath",
"instanceName":"LM1-LM2",
"startPos":
{
"instanceName":"LM1",
"pos":{"x":16.344,"y":6.621}
},
"endPos":
{
"instanceName":"LM2",
"pos":{"x":3.693,"y":6.621}
},
"controlPos1":{"x":12.127,"y":6.621},
"controlPos2":{"x":7.91,"y":6.621},
"property":
[
{"key":"direction","type":"int","value":"MA==","int32Value":0},
{"key":"movestyle","type":"int","value":"MA==","int32Value":0}
]
}
]
}
解析代码:
void MainWindow::handleJsonFile(QString FilePath)
{
//打开读取文件内容
QFile file(FilePath);
if(file.exists())
file.open(QIODevice::ReadOnly);
else return;
QByteArray data = file.readAll();
file.close();
//json文件转换成对象
QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
QJsonObject jsonObject = jsonDoc.object();
//列出json里的所有key
QStringList keys = jsonObject.keys();
for(int i=0;i<keys.size();++i)
qDebug()<<"key "<<i<<" is "<<keys.at(i);
//放大倍率
int mulriple = 40;
//根据key进行相应操作
if(keys.contains("header"))
{
//获取属性信息
QJsonObject JOB_header = jsonObject["header"].toObject();
QString mapType = JOB_header["mapType"].toString();
QString mapName = JOB_header["mapName"].toString();
QString mapVersion = JOB_header["version"].toString();
double resolution = JOB_header["resolution"].toDouble();
//打印map属性
ui->PTEInfo->clear();
ui->PTEInfo->appendPlainText(QString("mapType: ")+mapType);
ui->PTEInfo->appendPlainText(QString("mapName: ")+mapName);
ui->PTEInfo->appendPlainText(QString("mapVersion: ")+mapVersion);
ui->PTEInfo->appendPlainText(QString("resolution: %1").arg(resolution));
//获取场景大小信息
QJsonObject JOB_minPos = JOB_header["minPos"].toObject();
QJsonObject JOB_maxPos = JOB_header["maxPos"].toObject();
qreal scenePosX = JOB_minPos["x"].toDouble()*mulriple;
qreal scenePosY = JOB_minPos["y"].toDouble()*mulriple;
qreal sceneEdgeX = JOB_maxPos["x"].toDouble()*mulriple;
qreal sceneEdgeY = JOB_maxPos["y"].toDouble()*mulriple;
qreal sceneWidth = sceneEdgeX - scenePosX;
qreal sceneHight = sceneEdgeY - scenePosY;
scene = new QGraphicsScene(scenePosX,scenePosY,sceneWidth,sceneHight);
//添加场景,并显示矩形框
ui->graphicsView->setScene(scene);
scene->addRect(scenePosX,scenePosY,scene->width(),scene->height());
}
//显示普通点
if(keys.contains("normalPosList"))
{
QJsonArray posArray = jsonObject["normalPosList"].toArray();
//绘制点
for(auto i : posArray){
QJsonObject JOB_pos = i.toObject();
qreal x = JOB_pos["x"].toDouble()*mulriple;
qreal y = JOB_pos["y"].toDouble()*mulriple;
scene->addEllipse(x,y,1,1);
}
}
//显示高级点
if(keys.contains("advancedPointList"))
{
QJsonArray APosArray = jsonObject["advancedPointList"].toArray();
int AposCount = APosArray.count();
ui->PTEInfo->appendPlainText(QString("LandMarks Num: %1").arg(AposCount));
//绘制高级点
for(auto i : APosArray){
QJsonObject JOB_Apos = i.toObject();
QString className = JOB_Apos["className"].toString();
QString instanceName = JOB_Apos["instanceName"].toString();
QJsonObject JOB_pos = JOB_Apos["pos"].toObject();
qreal x = JOB_pos["x"].toDouble()*mulriple;
qreal y = JOB_pos["y"].toDouble()*mulriple;
QGraphicsItem* item_Apos = scene->addRect(x-10,y-10,20,20,QPen(QColor(Qt::yellow)),QBrush(QColor(Qt::blue)));
//将他加入可编辑图元列表里
this->items_editable.append(item_Apos);
//若标明方向,则绘制方向
if(JOB_Apos.keys().contains("dir")){
qreal angle = JOB_Apos["dir"].toDouble()*180/3.14;
QVector<QPointF> Tri = {{x,y-10},{x+10,y},{x,y+10}};
QGraphicsItem* item_pos_dir = scene->addPolygon(QPolygonF(Tri),QPen(QColor(Qt::red)),QBrush(QColor(Qt::red)));
//设置旋转中心
item_pos_dir->setTransformOriginPoint(x,y);
item_pos_dir->setRotation(angle);
item_pos_dir->setParentItem(item_Apos);
}
}
}
//显示曲线
if(keys.contains("advancedCurveList"))
{
QJsonArray CurArray = jsonObject["advancedCurveList"].toArray();
for(auto i : CurArray){
QJsonObject JOB_Cur = i.toObject();
QJsonObject JOB_Cur_startPos = JOB_Cur["startPos"].toObject();
QJsonObject JOB_Cur_endPos = JOB_Cur["endPos"].toObject();
QJsonObject startPos = JOB_Cur_startPos["pos"].toObject();
qreal x1 = startPos["x"].toDouble()*mulriple;
qreal y1 = startPos["y"].toDouble()*mulriple;
QJsonObject endPos = JOB_Cur_endPos["pos"].toObject();
qreal x2 = endPos["x"].toDouble()*mulriple;
qreal y2 = endPos["y"].toDouble()*mulriple;
QJsonObject controlPos1 = JOB_Cur["controlPos1"].toObject();
qreal cx1 = controlPos1["x"].toDouble()*mulriple;
qreal cy1 = controlPos1["y"].toDouble()*mulriple;
QJsonObject controlPos2 = JOB_Cur["controlPos2"].toObject();
qreal cx2 = controlPos2["x"].toDouble()*mulriple;
qreal cy2 = controlPos2["y"].toDouble()*mulriple;
//画贝塞斯曲线
//绘制贝塞斯曲线路径,初始化输入起始点,然后设置曲线的两个控制点和结束点
QPainterPath CurPath(QPointF(x1,y1));
CurPath.cubicTo(QPointF(cx1,cy1),QPointF(cx2,cy2),QPointF(x2,y2));
scene->addPath(CurPath,QPen(QColor(Qt::darkGreen)));
}
}
}