Reputation: 23
I have implemented a code that will take input from QLineEdit
and the data will be saved in a json file format.
void MainWindow::fileWriteOperationJson()
{
QString filename = "C:/Users/.../Documents/Qt/save.json";
QFile saveFile(filename);
saveFile.open(QIODevice::WriteOnly|QIODevice::Text);
if (!saveFile.open(QIODevice::WriteOnly))
{
qWarning("Couldn't open save file.");
}
QJsonObject obj; //this is the root
QJsonArray personalData;
QJsonObject json;
json["name"] = ui->nameLineEdit->text();
json["address"] = ui->addressLineEdit->toPlainText();
personalData.append(json);
obj["personalData"] = personalData;
QTextStream out(&saveFile);
out << QJsonDocument(obj).toJson(QJsonDocument::Indented);
}
Problem: When I open the json file, I want to find my data in the below format:
"name" = xyz
"address" = xyz
But, I am having result like this,
"address" = xyz
"name" = xyz
How to get this intended order?
Upvotes: 2
Views: 5468
Reputation: 169
The underlying problem is that QMap does not have an ordered form. Here's a possible solution by subclassing QVariantMap:
#ifndef ORDEREDVARIANTMAP_H
#define ORDEREDVARIANTMAP_H
#include <QtCore>
class OrderedVariantMap : public QMap<QString, QVariant> {
// Test:
// OrderedVariantMap test_map;
// test_map.insert("xxx", 1);
// test_map.insert("aaa", 2);
// test_map.insert("kkk", 3);
// test_map["321"] = 4;
// test_map["000"] = 5;
// test_map["123"] = 6;
// qDebug() << "QMap.keys()" << test_map.keys();
// qDebug() << "QMap.orderedKeys()" << test_map.orderedKeys();
// QVariant test_variant;
// test_variant.setValue(test_map);
// qDebug() << "test_variant.typeName()" << test_variant.typeName();
// OrderedVariantMap test_map_recovered = qvariant_cast<OrderedVariantMap>(test_variant);
// qDebug() << "test_map_recovered.orderedKeys()" << test_map_recovered.orderedKeys();
// Test results:
// QMap.keys() ("000", "123", "321", "aaa", "kkk", "xxx")
// QMap.orderedKeys() ("xxx", "aaa", "kkk", "321", "000", "123")
// test_variant.typeName() OrderedVariantMap
// test_map_recovered.orderedKeys() ("xxx", "aaa", "kkk", "321", "000", "123")
public:
OrderedVariantMap ( );
~OrderedVariantMap ( );
void
clear ( );
void // QMap::iterator
insert ( const QString &key,
const QVariant &value );
QVariant&
operator[] ( const QString &key );
const QVariant
operator[] ( const QString &key ) const;
const QString
orderedKey ( int index ) const;
const QVariant
orderedValue ( int index ) const;
QStringList
orderedKeys ( ) const ;
private:
QStringList Ordered_Keys;
protected:
};
Q_DECLARE_METATYPE(OrderedVariantMap)
#endif // ORDEREDVARIANTMAP_H
and
#include "OrderedVariantMap.h"
OrderedVariantMap::OrderedVariantMap ( ) : QMap ( ) {
}
OrderedVariantMap::~OrderedVariantMap ( ) {
}
QStringList
OrderedVariantMap::orderedKeys ( ) const {
return Ordered_Keys;
}
void
OrderedVariantMap::clear ( ) {
Ordered_Keys.clear();
QMap::clear();
}
void // QMap::iterator
OrderedVariantMap::insert ( const QString &key,
const QVariant &value ) {
Ordered_Keys.append(key);
QMap::insert(key, value);
}
QVariant&
OrderedVariantMap::operator[] ( const QString &key ) {
Ordered_Keys.append(key);
return QMap::operator [](key);
}
const QVariant
OrderedVariantMap::operator[] ( const QString &key ) const {
return this->value(key);
}
const QString
OrderedVariantMap::orderedKey ( int index ) const {
return Ordered_Keys[index];
}
const QVariant
OrderedVariantMap::orderedValue ( int index ) const {
return this->value(Ordered_Keys[index]);
}
More functionality could be provided, for example an ordered iterator.
Upvotes: 2
Reputation: 4873
Qt generates JSON data with keys sorted alphabetically. AFAIK, there is no option to get around it. You could try encapsulating objects with a single key/value pair into an array, though, and preserve the order:
[
{"address": xyz},
{"name": xyz}
]
Or you could try using a different storage format altogether.
Upvotes: 3
Reputation: 27611
JSON (JavaScript Object Notation) is a lightweight data-interchange format and as such, the structure is important, but the order of items is not.
If you need to print the items in a specific order, you'll need to extract them from Json into suitable data structures and handle that yourself.
Alternatively, you could save to a different format, but note that Qt's XML will act the same as Json. Perhaps a CSV may be more useful to you.
Upvotes: 4