#qt #ubuntu #qsettings
#qt #ubuntu #qsettings
Вопрос:
Я работаю в Ubuntu и хочу сохранить данные в QSettings. Во время выполнения данные сохраняются, после перезапуска приложения данные больше не считываются. Я читаю, что требуется дополнительный вызов синхронизации Linux, но я не могу найти, где это определено.
Во время запуска программы я успешно записал данные в объект QSettings и прочитал значение из сохраненного объекта QSettings.
У меня есть пользовательский класс, который может читать и записывать из / в QJsonObject
class User
{
public:
User() {}
User(const QStringamp; ruser_name, const QImageamp; rdisplay_image)
{
user_name = ruser_name;
display_image = rdisplay_image;
}
QString get_user_name() const { return user_name; }
void write(QJsonObject amp;json) const
{
json["user_name"] = user_name;
json["display_image"] = getImageInJsonValueFormat(display_image);
}
void read(const QJsonObject amp;json)
{
if (json.contains("user_name") amp;amp; json["user_name"].isString())
user_name = json["user_name"].toString();
if (json.contains("display_image"))
display_image = getImageFromJsonValueFormat(json["display_image"]);
}
private:
QString user_name;
QImage display_image;
};
Для работы с изображением и Json существуют две глобальные функции
QJsonValue getImageInJsonValueFormat(const QImageamp; image)
{
QByteArray image_ByteArray;
if (image.isNull() != true)
{
QBuffer image_buffer(amp;image_ByteArray);
image_buffer.open(QIODevice::WriteOnly);
image.save(amp;image_buffer, "png");
auto const encoded = image_buffer.data().toBase64();
return {QLatin1String(encoded)};
}
return QLatin1String("");
}
QImage getImageFromJsonValueFormat(const QJsonValueamp; imageJsonValue)
{
QImage image;
auto const encoded = imageJsonValue.toString().toLatin1();
image.loadFromData(QByteArray::fromBase64(encoded), "png");
return image;
}
Кроме того, три функции, кроме чтения списка из QSettings, для создания списка по умолчанию и для сохранения списка в QSettings.
QMap<QString, User> Build_user_list()
{
QMap<QString, User> user_list;
User User1("baur",QImage("/home/Downloads/bechambaur.png"));
user_list["baur"] = User1;
User User2("Muller",QImage("/home/Downloads/GerdMuller.png"));
user_list["Muller"] = User2;
return user_list;
}
void StoreUserList(const QMap<QString, User> user_list)
{
QJsonObject userListObject;
QJsonArray userListArray;
QMapIterator<QString,User> iterator(user_list);
while (iterator.hasNext())
{
iterator.next();
QJsonObject userJsonObject;
User userObj = iterator.value();
userObj.write(userJsonObject);
userListArray.append(userJsonObject);
}
userListObject["user_list"] = userListArray;
QJsonDocument userListDoc(userListObject);
QSettings user_settings;
user_settings.setValue("QSettingsApplication", userListDoc);
user_settings.sync();
}
QMap<QString, User> GetStoredList()
{
QMap<QString, User> user_list;
QSettings user_settings;
QJsonDocument userListDocRead = user_settings.value("QSettingsApplication", "").toJsonDocument();
QJsonObject userListObjectRead = userListDocRead.object();//["userlist"];
if (userListObjectRead.contains("user_list"))
{
if(userListObjectRead["user_list"].isArray())
{
QJsonArray userlistarray = userListObjectRead["user_list"].toArray();
user_list.clear();
for(int index = 0; index < userlistarray.size(); index)
{
QJsonObject json_user_object = userlistarray[index].toObject();
User userObject;
userObject.read(json_user_object);
user_list[userObject.get_user_name()] = userObject;
}
}
}
return user_list;
}
With this application ran for the subsequent times is not reading the value from QSettings which it reads successfully during the run
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// Why below list is empty after first successful run?
QMap<QString, User> user_listRead = GetStoredList();
if (user_listRead.size() == 0)
{
QMap<QString, User> user_list = Build_user_list();
StoreUserList(user_list);
QMap<QString, User> user_listRead = GetStoredList();
user_listRead = GetStoredList();
// This is is not empty, it reads contents successfully. What's wrong?
}
MainWindow w;
w.show();
return a.exec();
}
Я ожидаю, что данные будут постоянными. Где что-то идет не так?
Все содержимое файла
#include "mainwindow.h"
#include <QApplication>
#include <QString>
#include <QImage>
#include <QJsonObject>
#include <QBuffer>
#include <QSettings>
#include <QJsonArray>
#include <QJsonDocument>
QJsonValue getImageInJsonValueFormat(const QImageamp; image)
{
QByteArray image_ByteArray;
if (image.isNull() != true)
{
QBuffer image_buffer(amp;image_ByteArray);
image_buffer.open(QIODevice::WriteOnly);
image.save(amp;image_buffer, "png");
auto const encoded = image_buffer.data().toBase64();
return {QLatin1String(encoded)};
}
return QLatin1String("");
}
QImage getImageFromJsonValueFormat(const QJsonValueamp; imageJsonValue)
{
QImage image;
auto const encoded = imageJsonValue.toString().toLatin1();
image.loadFromData(QByteArray::fromBase64(encoded), "png");
return image;
}
class User
{
public:
User() {}
User(const QStringamp; ruser_name, const QImageamp; rdisplay_image)
{
user_name = ruser_name;
display_image = rdisplay_image;
}
QString get_user_name() const { return user_name; }
void write(QJsonObject amp;json) const
{
json["user_name"] = user_name;
json["display_image"] = getImageInJsonValueFormat(display_image);
}
void read(const QJsonObject amp;json)
{
if (json.contains("user_name") amp;amp; json["user_name"].isString())
user_name = json["user_name"].toString();
if (json.contains("display_image"))
display_image = getImageFromJsonValueFormat(json["display_image"]);
}
private:
QString user_name;
QImage display_image;
};
QMap<QString, User> Build_user_list()
{
QMap<QString, User> user_list;
User User1("baur",QImage("/home/Downloads/bechambaur.png"));
user_list["baur"] = User1;
User User2("Muller",QImage("/home/Downloads/GerdMuller.png"));
user_list["Muller"] = User2;
return user_list;
}
void StoreUserList(const QMap<QString, User> user_list)
{
QJsonObject userListObject;
QJsonArray userListArray;
QMapIterator<QString,User> iterator(user_list);
while (iterator.hasNext())
{
iterator.next();
QJsonObject userJsonObject;
User userObj = iterator.value();
userObj.write(userJsonObject);
userListArray.append(userJsonObject);
}
userListObject["user_list"] = userListArray;
QJsonDocument userListDoc(userListObject);
QSettings user_settings("userlist.conf", QSettings::NativeFormat);//(QSettings::IniFormat,QSettings::UserScope,"A","B");
user_settings.setValue("QSettingsApplication", userListDoc.toVariant());
user_settings.sync();
}
QMap<QString, User> GetStoredList()
{
QMap<QString, User> user_list;
QSettings user_settings("userlist.conf", QSettings::NativeFormat);
QVariant qvarval = user_settings.value("QSettingsApplication");
QJsonDocument userListDocRead = user_settings.value("QSettingsApplication").toJsonDocument();
QJsonObject userListObjectRead = userListDocRead.object();//["userlist"];
if (userListObjectRead.contains("user_list"))
{
if(userListObjectRead["user_list"].isArray())
{
QJsonArray userlistarray = userListObjectRead["user_list"].toArray();
user_list.clear();
for(int index = 0; index < userlistarray.size(); index)
{
QJsonObject json_user_object = userlistarray[index].toObject();
User userObject;
userObject.read(json_user_object);
user_list[userObject.get_user_name()] = userObject;
}
}
}
return user_list;
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMap<QString, User> user_listreRead;
// Why below list is empty after first successful run?
QMap<QString, User> user_listRead = GetStoredList();
if (user_listRead.size() == 0)
{
QMap<QString, User> user_list = Build_user_list();
StoreUserList(user_list);
user_listreRead = GetStoredList();
// This is is not empty, it reads contents successfully. What's wrong?
}
MainWindow w;
w.show();
return a.exec();
}
Содержимое userlist.conf является
[General]
QSettingsApplication=@Variant(000b000x1000x120u0s0x650r0_0l0i0s0t000t000x2000b000x2000x120u0s0x650r0_0n0x610m0x65000n000f0M0u0l0l0x650r000x1a0x640i0s0p0l0x610y0_0i0m0x610g0x65000n0000000b000x2000x120u0s0x650r0_0n0x610m0x65000n000b0x620x610u0r000x1a0x640i0s0p0l0x610y0_0i0m0x610g0x65000n0000)
Комментарии:
1. измените
QSettings* user_settings = new QSettings();
наQSettings user_settings;
. Синхронизация обычно вызывается в деструкторе QSettings, но при наличии указателя вы должны явно вызвать деструктор, вместо этого простое решение — не создавать указатель, но в вашем случае у вас утечка памяти2. Спасибо, я сделал это, но все еще безуспешно.