Russian Qt Forum

Qt => Общие вопросы => Тема начата: Гурман от Октябрь 31, 2017, 16:29



Название: Ещё бажина...
Отправлено: Гурман от Октябрь 31, 2017, 16:29
Понадобилось в INI файл сохранять массивы строк. У QSettings есть поддержка - beginWriteArray/beginReadArray/setArrayIndex/endArray. Использование простое. Как написано в доках Qt, так и сделал:

Запись:
Код:
void MainWindow::saveList( QStringList list )
{
    QSettings settings(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+
                       SETTINGSFORMAT, QSettings::IniFormat);
    int size;
    settings.beginWriteArray(LISTNAME, size = list.size());
    for( int i = 0; i < size; i++ )
    {
        settings.setArrayIndex( i );
        settings.setValue( ITEMNAME, list.at( i ) );
    }
    settings.endArray();
    settings.sync()
}

Чтение:
Код:
QStringList MainWindow::restoreList()
{
    QSettings settings(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+
                       SETTINGSFORMAT, QSettings::IniFormat);
    QStringList list;
    int size = settings.beginReadArray(LISTNAME);
    for( int i = 0; i < size; i++ )
    {
        settings.setArrayIndex( i );
        list << settings.value(ITEMNAME).toString();
    }
    settings.endArray();
    return list;
}

Запускаю, сохраняю список из 10 строк. Смотрю в INI файл - сохранился, 10 строк, в конце перменная size=10. Хорошо. Запускаю снова, читаю список, отображаю - есть 10 строк. Хорошо. Удаляю из списка 5 строк вперемежку, не подряд. Сохраняю снова, читаю... БУМ! В INI файле по-прежнему 10 строк. Первые 5 - те, которые я оставил, и соответственно сохранил. Следом за ними хвост из 5 строк от предыдущих 10, которые сохранял первый раз. И потом переменная size=5. Запускаю снова, читаю - получаю конечно же 5 строк. Отображаю - да, всё верно, первые 5. То есть, у меня QStringList.size() == 5. Сохраняю снова этот QStringList, смотрю INI файл - !@!@#$#... там 10 строк, первые 5 правильные потом хвост из лишних 5.

Что это значит? - Что если вы сохраните 1 раз 4235432 элементов массива в INI файле, а потом будете всё время сохранять и использовать только первые 2 элемента, то QSettings будет всё равно постоянно таскать туда-сюда и хранить на носителе ненужные 4235430 записей...  >:(

Руки отрывать надо за такое проектирование.

Баг репорт создал.


Название: Re: Ещё бажина...
Отправлено: Гурман от Октябрь 31, 2017, 17:08
В общем лечится это самостоятельной чисткой записей в QSettings.

Код:
void MainWindow::saveList( QStringList list )
{
    QSettings settings(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+
                       SETTINGSFORMAT, QSettings::IniFormat);
    int size;
    settings.remove( LISTNAME )                                         // added
    settings.beginWriteArray(LISTNAME, size = list.size());
    for( int i = 0; i < size; i++ )
    {
        settings.setArrayIndex( i );
        settings.setValue( ITEMNAME, list.at( i ) );
    }
    settings.endArray();
    settings.sync()
}

И хрена с два где-либо описано, что заполнение массивов в настройках их не очищает. По идее, очистка должна быть внутри beginWriteArray(), возможно по третьему (сейчас отсутствующему) параметру bool clean=true.


Название: Re: Ещё бажина...
Отправлено: __Heaven__ от Октябрь 31, 2017, 17:21
Можно ещё воспользоваться QVariantList и обойтись без массивов.


Название: Re: Ещё бажина...
Отправлено: Racheengel от Октябрь 31, 2017, 20:01
А еще названия групп возвращаются не в том порядке, в котором они записаны в файле.
Тоже раздражает, приходилось свой парсер писать...


Название: Re: Ещё бажина...
Отправлено: titan83 от Октябрь 31, 2017, 21:14
Тоже делал свой парсер. Но пришел к тому, что  в xml хранить удобнее, можно прямо в объекты свойства читать\писать.


Название: Re: Ещё бажина...
Отправлено: Old от Октябрь 31, 2017, 21:42
А еще QSettings не считает символ '#' началом комментария. Будте осторожны. :)

key1 = 10
key2 = 20   # shit comment
key3 = 30   ; good comment

Втыкался я на такой ерунде. :)