How to create/read/write JSON files in Qt5
Example: Read json from file
/* 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();
}
OUTPUT
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"
Example: Read json from string
Assign json to string as below and use the readJson()
function shown before:
val =
' {
"appDesc": {
"description": "SomeDescription",
"message": "SomeMessage"
},
"appName": {
"description": "Home",
"message": "Welcome",
"imp":["awesome","best","good"]
}
}';
OUTPUT
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"
How to parsing JSON file(Array) in Qt5 (C++), using QJsonArray
Since the data does not have a JSON format (it is ill-formed, see RFC 7159), but if it is in parts, what we must do is to separate it, for that we use QRegularExpresion
, and we verify that the data has an appropriate format, then the code is similar to your code.
Code:
#include <QCoreApplication>
#include <QFile>
#include <QDebug>
#include <QRegularExpression>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
int main(int argc, char *argv[]){
QCoreApplication a(argc, argv);
QFile file("test.json");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){
qWarning() << "Could not open file!";
return 0;
}
const auto& data = QString(file.readAll());
file.close();
QRegularExpression regex("\\[|\\]");
const auto& jsons = data.split(regex);
for(const auto& json : jsons)
if(!json.trimmed().isEmpty()){
const auto& formattedJson = QString("[%1]").arg(json);
const auto& doc = QJsonDocument::fromJson(formattedJson.toUtf8());
if(doc.isArray())
for(const auto& item : doc.array()){
const auto& obj = item.toObject();
const auto& keys = obj.keys();
for(const auto& key : keys){
if(key == "n")
qDebug() << key << obj[key].toString();
else
qDebug() << key << obj[key].toInt();
}
}
}
return a.exec();
}
Output:
"b" 467
"h" 334
"l" 232
"n" "person"
"p" 0
"r" 420
"t" 133
"th" 0
"w" 188
"b" 303
"h" 141
"l" 1152
"n" "person"
"p" 0
"r" 1279
"t" 162
"th" 0
"w" 127
"b" 470
"h" 339
"l" 230
"n" "person"
"p" 0
"r" 409
"t" 131
"th" 0
"w" 179
Read Json from https in qt
To add key-values to the url you must use QUrlQuery
as shown below:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
nam = new QNetworkAccessManager(this);
connect(nam, &QNetworkAccessManager::finished, this, &MainWindow::onResult);
QString lang = "ar";
QString text = "Hello World";
QString key = "trnsl.1.1.20180627T161429Z.7e64c91dd2016a6c.9901da9a44bc324388a2460776ab55b2d72b4c5a";
QUrlQuery query;
query.addQueryItem("key", key);
query.addQueryItem("lang", lang);
query.addQueryItem("text", text);
QUrl url("https://translate.yandex.net/api/v1.5/tr.json/translate");
url.setQuery(query);
qDebug()<< "url: "<< url.toString(QUrl::FullyEncoded);
nam->get(QNetworkRequest(url));
}
void MainWindow::onResult(QNetworkReply *reply){
if(reply->error() == QNetworkReply::NoError){
QByteArray result = reply->readAll();
QJsonDocument jsonResponse = QJsonDocument::fromJson(result);
QJsonObject obj = jsonResponse.object();
qDebug()<<"code: " << obj["code"].toInt();
qDebug()<<"lang: " << obj["lang"].toString();
QJsonArray array = obj["text"].toArray();
for(const QJsonValue & value : array) {
qDebug()<< "text: " <<value.toString();
}
}
else
qDebug() << "ERROR";
reply->deleteLater();
}
Output:
url: "https://translate.yandex.net/api/v1.5/tr.json/translate?key=trnsl.1.1.20180627T161429Z.7e64c91dd2016a6c.9901da9a44bc324388a2460776ab55b2d72b4c5a&lang=ar&text=Hello%20World"
code: 200
lang: "en-ar"
text: "مرحبا العالم"
If the url generated is revised, it differs from the concatenation:
Concatenation:
...&text=Hello World
Encoded:
...&text=Hello%20World
Qt parsing JSON using QJsonDocument, QJsonObject, QJsonArray
I figured it out:
QStringList propertyNames;
QStringList propertyKeys;
QString strReply = (QString)reply->readAll();
QJsonDocument jsonResponse = QJsonDocument::fromJson(strReply.toUtf8());
QJsonObject jsonObject = jsonResponse.object();
QJsonArray jsonArray = jsonObject["properties"].toArray();
foreach (const QJsonValue & value, jsonArray) {
QJsonObject obj = value.toObject();
propertyNames.append(obj["PropertyName"].toString());
propertyKeys.append(obj["key"].toString());
}
Parsing JSON starting with bracket `[` with Qt5
The answere is simple - you have to call QJsonDocument::array()
instead of object
:
QJsonArray sett2 = d.array();
How to use Qt/C++ to create/read/write files and store settings local with the program
You can use QSettings
with any file, with constructor QSettings::QSettings ( const QString & fileName, Format format, QObject * parent = 0 )
.
To get the program directory, you can use QCoreApplication::applicationDirPath()
.
So, answer to your question, statement to put after creation of QApplication instance:
QSettings *settings = new QSettings(
QCoreApplication::applicationDirPath() + "/settings.ini",
QSettings::IniFormat,
qApp);
But, as noted in the comments under question, if you're making your program for general distribution, you should use the OS default. Examine all the constructors of QSettings
to see what it can do. User does not often have write permission in the application directory. Note that you can also store settings to Windows registry with QSettings::NativeFormat.
How to save and load a QJsonDocument to a file?
No need for converting to string and back. With QSettings and QVariant classes you can easily do that. Create QVariant
object from QJsonDocument
and save it with QSettings
. Look at functions QJsonDocument::fromVariant and QJsonDocument::toVariant. Combine them with QSettings
class and specifically void QSettings::setValue ( const QString & key, const QVariant & value ) method, that works well with QVariant
and that's it.
Also QSettings
class has this constructor QSettings::QSettings ( const QString & fileName, Format format, QObject * parent = 0 )
that would allow you to set path to the file - fileName
variable
Qt Json Parsing c++
If you review the result of POSTMAN in raw mode you get the following:
What QNAM gets but POSTMAN has another algorithm to extract the json:
So a possible solution is to remove the unwanted element: <br><br>NO OF ROWDATA: 1
, for this it takes advantage that the json must start with "{" so the superior substring is used.
QUrl ava_url("http://pinundpin.de/wsdemo/atgdemoapi_v3/index.php");
QNetworkRequest ava_request(ava_url);
ava_request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
QNetworkAccessManager *manager = new QNetworkAccessManager();
QEventLoop loop;
QObject::connect(manager,
&QNetworkAccessManager::finished,
&loop,
&QEventLoop::quit);
QByteArray postData;
QString Username = "testwebser";
QString Passwd = "2017@QWEasdZXC";
postData.append("action=login&");
postData.append("password="+Passwd+"&");
postData.append("username="+Username);
QNetworkReply *reply = manager->post(ava_request,postData);
loop.exec();
QByteArray response = reply->readAll();
QByteArray json = response.mid(response.indexOf("{"));
QJsonDocument temp = QJsonDocument::fromJson(json);
QJsonObject jsonObj = temp.object();
QJsonObject errorObj = jsonObj["error"].toObject();
qDebug()<<"error: "
<<"errorcode: "<< errorObj["errorcode"].toInt()
<<"errorstring: "<< errorObj["errorstring"].toString();
qDebug() <<"login"<< jsonObj["login"].toInt();
qDebug() << "logintoken"<<jsonObj["logintoken"].toString();
Output:
error: errorcode: 0 errorstring: ""
login 1
logintoken "cc7e46f34e0a268cecbaaeaad41b0ae2727cc7196b632574a4db16544576d012"
Related Topics
Exclude Source File in Compilation Using Makefile
Member Function with Static Linkage
Converting Between C++ Std::Vector and C Array Without Copying
How Does the C++ Compiler Know Which Implementation of a Virtual Function to Call
How to Create Objects While Adding Them into a Vector
Cannot Open Include File: 'Stdio.H' - Visual Studio Community 2017 - C++ Error
How to Encode a String to Base64 Using Only Boost
Cannot Open Include File: 'Ctype.H': No Such File or Directory
Why Not Just Use Random_Device
C++ Range/Xrange Equivalent in Stl or Boost
C++ How to Allocate Memory Dynamically on Stack
Using Condition Variable in a Producer-Consumer Situation
Why Is Std::Vector::Operator[] 5 to 10 Times Faster Than Std::Vector::At()
Opinions on Type-Punning in C++
How to Use Memcpy in C++ to Copy Classes That Have No Pointers or Virtual Functions
How to Compile Openssl for X64