Сохраните пользовательский экземпляр шаблона QMap в QSettings в удобочитаемой форме - PullRequest
0 голосов
/ 28 сентября 2018

В своем коде я использую механизм QSettings для сохранения и загрузки своего собственного класса MyClass внутри QMap<unsigned int, MyClass> в файлы конфигурации.

Я знаю, как зарегистрировать свои собственные типы в QMetaObject, чтобы я могиспользуйте их с QVariant.Это позволяет сохранять их с помощью QSettings.См. Рабочий код ниже.

Однако представление этих типов в реальном конфигурационном файле, в который я пишу, никоим образом не является читабельным. Есть ли способ сделать пользовательскую карту более читабельной в текстовом редакторе, чтобы я мог вручную изменить конфиги вне Qt?

Код, который сохраняет мои пользовательские типы в конфигурации:

struct MyClass
{
    unsigned int id;
    QString name;
    QString value;

    friend QDataStream & operator<< (QDataStream &arch, const MyClass& c)
    {
        return arch << c.id << c.name << c.value;
    }
    friend QDataStream & operator>> (QDataStream &arch, MyClass& c)
    {
        return arch >> c.id >> c.name >> c.value;
    }
};
Q_DECLARE_METATYPE(MyClass)
typedef QMap<unsigned int, MyClass> MyMap;

int main(int argc, char *argv[])
{
   MyMap map;
    map.insert(100, {100, "name1", "value1"});
    map.insert(101, {101, "name2", "value2"});
    map.insert(200, {200, "name3", "value3"});

    qRegisterMetaTypeStreamOperators<MyMap>("MyMap");
    QSettings conf("/home/dave/temp/myfile.conf", QSettings::IniFormat);
    conf.setValue("myMapping", QVariant::fromValue(map));
    conf.sync();
}

Записанный файл конфигурации:

[General]
myMapping="@Variant(\0\0\0\x7f\0\0\0\x13QMap<uint,MyClass>\0\0\0\0\x3\0\0\0\xc8\0\0\0\xc8\0\0\0\n\0n\0\x61\0m\0\x65\0\x33\0\0\0\f\0v\0\x61\0l\0u\0\x65\0\x33\0\0\0\x65\0\0\0\x65\0\0\0\n\0n\0\x61\0m\0\x65\0\x32\0\0\0\f\0v\0\x61\0l\0u\0\x65\0\x32\0\0\0\x64\0\0\0\x64\0\0\0\n\0n\0\x61\0m\0\x65\0\x31\0\0\0\f\0v\0\x61\0l\0u\0\x65\0\x31)"

1 Ответ

0 голосов
/ 28 сентября 2018

Qt позаботится о сериализации / десериализации вашей карты - к сожалению, это не учитывает удобочитаемость человеком.

Вам потребуется вручную обработать сериализацию / десериализацию всей карты и записать / прочитать QString (или что-то в этом роде), например

QString serialize(const QMap<int, MyClass>& mapToSerialize)
{
    QStringList result;
    for(int key : mapToSerialize.keys())
    {
        result.append("%1%2%3).arg(QString::number(i), SEPARATOR_TOKEN, serialize(mapToSerialize.value(i));
    }
    return result.join(MAP_SEPARATOR_TOKEN);
}

Это, конечно, имеет тот недостаток, что вам 1) нужно написать функции сериализации / десериализации для карты и вашего класса и 2) вам нужно обрабатывать все специальныеслучаи (экранирование специальных символов, анализ неверных данных и т. д.)

...