Где определена функция sync() для Linux. Запись данных в QSettings не сохраняется после закрытия приложения

#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. Спасибо, я сделал это, но все еще безуспешно.