Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > [Qt4]Упаковка в QSettings QList<QString>


Автор: BiTOk 20.1.2011, 15:19
Добрый день. Бьюсь над проблемой: как засунуть в QSettings объект QList<QString>. Почитал в инете, получилось так:
Код

    QList<QString> recentFilesList;

    Q_DECLARE_METATYPE(QList<QString>);

    appSettings = new QSettings("MySoft", "IDE");
    recentFilesList = appSettings->value("recentFiles/files", QVariant(QList<QString>())).value<QList<QString> >();
    recentFilesList.append("Test");
    appSettings->setValue("recentFiles/files", QVariant(recentFilesList));


В итоге получаем файл настроек:
[recentFiles]
files=Test

После повторного запуска recentFilesList пуст, т.е. пустой QList<QString>. Как правильно реализовать задуманное?

Автор: borisbn 20.1.2011, 15:27
http://doc.qt.nokia.com/4.7-snapshot/qsettings.html#beginWriteArray
http://doc.qt.nokia.com/4.7-snapshot/qsettings.html#beginReadArray

Автор: BiTOk 20.1.2011, 15:34
Интересное решение. А можно как-то так, чтобы сразу припаковал весь QList, а потом вытащил его же, не думая о его размере и т.д.?
ADD
Попробовал добавить несколько элементов в QList, в файл настроек они записываются верно, стало быть неверно реализовано чтение.
Код

recentFilesList = appSettings->value("recentFiles/files", QVariant(QList<QString>())).value<QList<QString> >();

т.е. что-то здесь не верно.

Автор: borisbn 20.1.2011, 18:18
В случае со строками и с именами файлов, я бы сделал проще:
Код

// запись:
settings->setValue( "recent", recentFilesList.join( ";" ) );
// чтение
recentFilesList = settings.value( "recent" ).split( ";" );

только recentFilesList должен быть не QList< QString >, а QStringList

Автор: Batbko 20.1.2011, 23:07
BiTOk, твоя ошибка в том что ты регистрируешь класс в метаобьектной системе только в compile-time, что всего лишь делает доступным использование шаблонной функции QVariant::value() и QVariant::setValue(), а для этого тип элемента с которым будет работать функция надо знать на этапе компиляции.
QSettings же использует рантайм информацию о типе и, не имеет никакого понятия о том как обрабатывать обьекты класса QList<QString>. То что тебе удалось что либо записать для меня пока-что необьяснимо.
Для того что-бы зарегистрировать класс в метаобьектной системе так, чтобы о нём имелась run-time информация необъодимо использовать функцию  qRegisterMetaType(). Для того чтобы можно было (де)серриализовать обьект необходимо определить операторы вида :
QDataStream &operator<<(QDataStream &out, const Регистрируемый_класс &myObj) 
и QDataStream &operator>>(QDataStream &in, Регистрируемый_класс &myObj)
(для класса QList эти операторы уже реализованны разработчиками). Затем надо  вызвать функцию qRegisterMetaTypeStreamOperators(), и тип станет доступен к использованию в любых средствах типа QSettings.

P.S. пример в аттаче.

Автор: panter 21.1.2011, 00:04
Пиплы, что-то я вас не пойму. 
QVariant ( const QStringList & val )
Т.е. QStringList отлично сохраняется в QSettings. А что есть QStringList? На крайняк есть QStringList ( const QList<QString> & other )

Автор: Batbko 21.1.2011, 00:13
ну дык для общего развития smile

Автор: BiTOk 21.1.2011, 11:16
borisbn, спасибо за решение.

Batbko, спасибо за науку, не шарю ещё в метаобъектах.. Буду разбираться.

Автор: borisbn 21.1.2011, 11:21
Цитата(panter @  21.1.2011,  00:04 Найти цитируемый пост)
На крайняк есть QStringList ( const QList<QString> & other )

такого же простого обратного, к сожалению, нет.

Автор: panter 21.1.2011, 14:14
borisbn, QList<T> QList::mid ( int pos, int length = -1 ) const разве не оно?

Автор: borisbn 21.1.2011, 14:53
panter, это чего-то я протупил. Можно ещё проще:
Код

    QList< QString > recentFilesList;
...    
    QSettings settings;
    // запись:
    settings.setValue( "recent", QStringList( recentFilesList ) );


    // чтение. Тут используется 
    // QList<T> & QList::operator= ( const QList<T> & other )
    // а QStringList, являясь наследником от QList< QString >,
    // легко можно преобразовывать к QList<QString> &
    recentFilesList = settings.value( "recent" ).toStringList();

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)