【问题标题】:How to create/read/write JSON files in Qt5如何在 Qt5 中创建/读取/写入 JSON 文件
【发布时间】:2013-03-31 08:35:12
【问题描述】:

Qt5 有一个新的 JSON 解析器,我想使用它。问题在于,用外行的话来说,这些函数的作用以及如何用它编写代码并不太清楚。否则我可能读错了。

我想知道在Qt5中创建JSON文件的代码以及“封装”是什么意思。

【问题讨论】:

  • Min Lin:QJson 与 Qt5 相比有点过时了(甚至不确定它是否被移植),因为它带来了自己的 Json 实现。吉姆·基格:你试过什么?
  • This reference page 具有 QJsonDocument::QJsonDocument() 和 QJsonDocument::QJsonDocument(const QJsonDocument & other) 函数。我试过 QJsonDocument 但它似乎没有创建任何东西。

标签: c++ json qt qt5


【解决方案1】:

一个关于如何使用它的例子会很棒。 Qt forum 有几个例子,但你说得对,应该扩展官方文档。

QJsonDocument 本身确实不会产生任何东西,您必须将数据添加到其中。这是通过QJsonObjectQJsonArrayQJsonValue 类完成的。顶级项需要是数组或对象(因为1 不是有效的 json 文档,而 {foo: 1} 是。)

【讨论】:

  • 在调查了这个之后,我想我会继续使用 QSettings 而不是在某些事情上使用 JSON。感谢您的帮助。
【解决方案2】:

示例:从文件中读取 json

/* test.json */
{
   "appDesc": {
      "description": "SomeDescription",
      "message": "SomeMessage"
   },
   "appName": {
      "description": "Home",
      "message": "Welcome",
      "imp":["awesome","best","good"]
   }
}


void readJson()
   {
      QString val;
      QFile file;
      file.setFileName("test.json");
      file.open(QIODevice::ReadOnly | QIODevice::Text);
      val = file.readAll();
      file.close();
      qWarning() << val;
      QJsonDocument d = QJsonDocument::fromJson(val.toUtf8());
      QJsonObject sett2 = d.object();
      QJsonValue value = sett2.value(QString("appName"));
      qWarning() << value;
      QJsonObject item = value.toObject();
      qWarning() << tr("QJsonObject of description: ") << item;

      /* in case of string value get value and convert into string*/
      qWarning() << tr("QJsonObject[appName] of description: ") << item["description"];
      QJsonValue subobj = item["description"];
      qWarning() << subobj.toString();

      /* in case of array get array and convert into string*/
      qWarning() << tr("QJsonObject[appName] of value: ") << item["imp"];
      QJsonArray test = item["imp"].toArray();
      qWarning() << test[1].toString();
   }

输出

QJsonValue(object, QJsonObject({"description": "Home","imp": ["awesome","best","good"],"message": "YouTube"}) ) 
"QJsonObject of description: " QJsonObject({"description": "Home","imp": ["awesome","best","good"],"message": "YouTube"}) 
"QJsonObject[appName] of description: " QJsonValue(string, "Home") 
"Home" 
"QJsonObject[appName] of value: " QJsonValue(array, QJsonArray(["awesome","best","good"]) ) 
"best" 

示例:从字符串中读取 json

如下所示将 json 分配给字符串,并使用前面显示的 readJson() 函数:

val =   
'  {
       "appDesc": {
          "description": "SomeDescription",
          "message": "SomeMessage"
       },
       "appName": {
          "description": "Home",
          "message": "Welcome",
          "imp":["awesome","best","good"]
       }
    }';

输出

QJsonValue(object, QJsonObject({"description": "Home","imp": ["awesome","best","good"],"message": "YouTube"}) ) 
"QJsonObject of description: " QJsonObject({"description": "Home","imp": ["awesome","best","good"],"message": "YouTube"}) 
"QJsonObject[appName] of description: " QJsonValue(string, "Home") 
"Home" 
"QJsonObject[appName] of value: " QJsonValue(array, QJsonArray(["awesome","best","good"]) ) 
"best" 

【讨论】:

  • 我发现这个非常好的例子是一颗明亮闪亮的希望之星,并且一直遵循这个例子。但是,当我调试示例时,条目的值显示为 null。这是关于如何在 QT 中创建、读取和写入 JSON 文件的唯一示例“逐步”吗?我无法弄清楚我可能做错了什么。使用 QT Creator 3.0.1。谢谢
  • @Shawn 在 QT Creator 的帮助选项卡中,搜索 JSON Save Game Example。这几乎演示了读取和写入 JSON 值(包括数组)所需的一切。 JSON Save Game Example
  • 如果你改用QByteArray,你可以跳过将utf-8字节转换为utf-16并返回(QString,toUtf8())。
  • 加载整个文件到字符串然后解析字符串,真的吗?!
  • 在我检查了可选的错误参数之前,我遇到了这个问题:QJsonParseError err; QByteArray utf8String = jsonString.toUtf8(); QJsonDocument d = QJsonDocument::fromJson(utf8String, &amp;err);
【解决方案3】:

遗憾的是,许多 JSON C++ 库的 API 使用起来并不简单,而 JSON 旨在易于使用。

所以我在上面的答案之一所示的 JSON 文档上尝试了 gSOAP tools 中的 jsoncpp,这是使用 jsoncpp 生成的代码,用于在 C++ 中构造一个 JSON 对象,然后以 JSON 格式写入 std: :cout:

value x(ctx);
x["appDesc"]["description"] = "SomeDescription";
x["appDesc"]["message"] = "SomeMessage";
x["appName"]["description"] = "Home";
x["appName"]["message"] = "Welcome";
x["appName"]["imp"][0] = "awesome";
x["appName"]["imp"][1] = "best";
x["appName"]["imp"][2] = "good";
std::cout << x << std::endl;

这是 jsoncpp 生成的代码,用于从 std::cin 解析 JSON 并提取其值(根据需要替换 USE_VAL):

value x(ctx);
std::cin >> x;
if (x.soap->error)
  exit(EXIT_FAILURE); // error parsing JSON
#define USE_VAL(path, val) std::cout << path << " = " << val << std::endl
if (x.has("appDesc"))
{
  if (x["appDesc"].has("description"))
    USE_VAL("$.appDesc.description", x["appDesc"]["description"]);
  if (x["appDesc"].has("message"))
    USE_VAL("$.appDesc.message", x["appDesc"]["message"]);
}
if (x.has("appName"))
{
  if (x["appName"].has("description"))
    USE_VAL("$.appName.description", x["appName"]["description"]);
  if (x["appName"].has("message"))
    USE_VAL("$.appName.message", x["appName"]["message"]);
  if (x["appName"].has("imp"))
  {
    for (int i2 = 0; i2 < x["appName"]["imp"].size(); i2++)
      USE_VAL("$.appName.imp[]", x["appName"]["imp"][i2]);
  }
}

此代码使用 gSOAP 2.8.28 的 JSON C++ API。我不希望人们更改库,但我认为这种比较有助于正确看待 JSON C++ 库。

【讨论】:

    【解决方案4】:

    QT 下的 JSON 实际上是相当令人愉快的——我很惊讶。这是一个如何创建具有某种结构的 JSON 输出的示例。

    请原谅我没有解释这些字段的含义 - 这是一个业余无线电处理输出脚本。

    这是 QT C++ 代码

    void CabrilloReader::JsonOutputMapper()
    {
      QFile file(QDir::homePath() + "/1.json");
      if(!file.open(QIODevice::ReadWrite)) {
          qDebug() << "File open error";
        } else {
          qDebug() <<"JSONTest2 File open!";
        }
    
      // Clear the original content in the file
      file.resize(0);
    
      // Add a value using QJsonArray and write to the file
      QJsonArray jsonArray;
    
      for(int i = 0; i < 10; i++) {
          QJsonObject jsonObject;
          CabrilloRecord *rec= QSOs.at(i);
          jsonObject.insert("Date", rec->getWhen().toString());
          jsonObject.insert("Band", rec->getBand().toStr());
          QJsonObject jsonSenderLatObject;
          jsonSenderLatObject.insert("Lat",rec->getSender()->fLat);
          jsonSenderLatObject.insert("Lon",rec->getSender()->fLon);
          jsonSenderLatObject.insert("Sender",rec->getSender_call());
          QJsonObject jsonReceiverLatObject;
          jsonReceiverLatObject.insert("Lat",rec->getReceiver()->fLat);
          jsonReceiverLatObject.insert("Lon",rec->getReceiver()->fLon);
          jsonReceiverLatObject.insert("Receiver",rec->getReceiver_call());
          jsonObject.insert("Receiver",jsonReceiverLatObject);
          jsonObject.insert("Sender",jsonSenderLatObject);
          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";
    }
    

    它需要一个内部 QT 结构(一个指向 CabrilloRecord 对象的指针列表......您只需忽略它)并提取一些字段。然后这些字段以嵌套的 JSON 格式输出,如下所示。

    [
        {
            "Band": "20",
            "Date": "Sat Jul 10 12:00:00 2021",
            "Receiver": {
                "Lat": 36.400001525878906,
                "Lon": 138.3800048828125,
                "Receiver": "8N3HQ       "
            },
            "Sender": {
                "Lat": 13,
                "Lon": 122,
                "Sender": "DX0HQ       "
            }
        },
        {
            "Band": "20",
            "Date": "Sat Jul 10 12:01:00 2021",
            "Receiver": {
                "Lat": 36.400001525878906,
                "Lon": 138.3800048828125,
                "Receiver": "JA1CJP      "
            },
            "Sender": {
                "Lat": 13,
                "Lon": 122,
                "Sender": "DX0HQ       "
            }
        }]
    

    我希望这能加快其他人在这个主题上的进展。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多