0

I am trying to log data from 3 sensors to a json file. All I want to be able to accomplish is to write the Speed, Latitude and Longitude to a Json file, with an object containing each of the above. That is a json file that contains one route object, n sub objects each of which contain speed, latitude, longitude.

These 3 values I get from 3 global QList lists. Below is the json file which is stored locally. (The double values are not actual values, just for testing purposes)

 {
"Sensordata": [
 {
   "Speed": 1,
   "GPSLat":-12.5687,
   "GPSLong":26.125546

 },
 {
  "Speed": 1,
  "GPSLat":-12.5687,
  "GPSLong":26.125546
}
]
}

This is what the json must look like and when I add it must be formatted in the same way

void MainWindow::save_to_json()  {
QFile file_obj(".../SensorData.json");
if(!file_obj.open(QIODevice::ReadOnly)){
    qDebug()<<"Failed to open "<<"SensorData.json";
    exit(1);
}


QTextStream file_text(&file_obj);
QString json_string;
json_string = file_text.readAll();
file_obj.close();
QByteArray data_json = json_string.toLocal8Bit();
QJsonDocument doc = QJsonDocument::fromJson(data_json);

QJsonObject rootObj = doc.object();
QJsonValue SensorData = rootObj.value("SensorData");

if(!SensorData.isArray())
{
    // array expected - handle error
}

QJsonArray SensorDataArray = SensorData.toArray();

QJsonObject newObject;
newObject["Speed"] = speed_array.takeFirst();
newObject["GPSLat"] = gps_lat.takeFirst();
newObject["GPSLong"] = gps_long.takeFirst();

SensorDataArray.push_back(newObject);


}

ASSERT: "!isEmpty()" in file /home/username/Qt/5.12.1/gcc_64/include        /QtCore/qlist.h, line 347
11:32:55: The program has unexpectedly finished.
11:32:55: The process was ended forcefully.

This is the error the above code creates.

ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
Benjamin Beer
  • 77
  • 1
  • 12

1 Answers1

0

To modify the data, given your example, you need to check if the contained data in the QJsonDocument is an array or a simple object. In your case, I suppose you want to append data to an array. Try something like this:

// Read the data
const QString filename = "example.json";
QJsonDocument doc = read(filename);

// Check that it's an array and append new data
QJsonValue sensorData = doc.value("SensorData");
if (!sensorData.isArray()) {
    // if the doc is empty you may want to create it
} 

// Get the array and insert the data
auto array = sensorData.array();
array.append(QJsonObject{
    {"Speed", speed_array.takeFirst()},
    {"GPSLat", gps_lat.takeFirst()},
    {"GPSLong",gps_long.takeFirst(),
});

// Restore your sensor data
doc.setObject(QJsonObject{{"SensorData", array}});

// Write the new data
write(filename, doc); 

A helper functions to read/write JSON documents may avoid the mistake of open/closing a file:

QJsonDocument read(const QString& filename) {
    QFile file(filename);
    file.open(QIODevice::ReadOnly | QIODevice::Text);
    const QString val = file.readAll();
    file.close();
    return QJsonDocument::fromJson(val.toUtf8());
}

void write(const QString& filename, const QJsonDocument& document) {
    QFile file(filename);
    file.open(QFile::WriteOnly | QFile::Text | QFile::Truncate);
    file.write(document.toJson());
    file.close();
}

Updates

To not overwrite the original doc, you must update the field of the root object or use QJsonValueRef.

// Get a reference to your array 
QJsonObject root = doc.object();
QJsonValueRef ref = root.find("SensorData").value();

// get the array and insert the data
QJsonArray array = ref.toArray();
array.append(QJsonObject{
    {"Speed", speed_array.takeFirst()},
    {"GPSLat", gps_lat.takeFirst()},
    {"GPSLong",gps_long.takeFirst(),
});

// Update the ref with the new data
ref = array

// update the modified data in the json document
doc.setObject(root);
mohabouje
  • 3,867
  • 2
  • 14
  • 28