Results 1 to 7 of 7

Thread: Serialising QList<int> with QSettings

  1. #1
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Question Serialising QList<int> with QSettings

    Hi,

    I am trying, using QSettings, to serialise various settings, which are of type QList<int>. Now, it all works fine on Windows and OS X, but for some reasons it doesn't on Linux. Here is how I do it to load and save some of those settings. Notice that I register QList<int> as a meta-type (using qRegisterMetaTypeStreamOperators), so I believe I should be all fine and, indeed, it all works as I would expect on Windows and OS X, but not on Linux. On Linux, I get a bunch of warnings like:

    QVariant::load: unable to load type 1038.
    QVariant::load: unable to load type 1038.
    QVariant::save: unable to save type 'QList<int>' (type id: 1038).

    QVariant::save: unable to save type 'QList<int>' (type id: 1038).

    QVariant::load: unable to load type 1038.
    QVariant::load: unable to load type 1038.
    QVariant::save: unable to save type 'QList<int>' (type id: 1038).

    QVariant::save: unable to save type 'QList<int>' (type id: 1038).

    QVariant::load: unable to load type 1038.
    QVariant::load: unable to load type 1038.
    QVariant::save: unable to save type 'QList<int>' (type id: 1038).

    QVariant::save: unable to save type 'QList<int>' (type id: 1038).

    QVariant::load: unable to load type 1038.
    QVariant::load: unable to load type 1038.
    QVariant::save: unable to save type 'QList<int>' (type id: 1038).

    QVariant::save: unable to save type 'QList<int>' (type id: 1038).

    QVariant::load: unable to load type 1038.
    QVariant::load: unable to load type 1038.
    QVariant::save: unable to save type 'QList<int>' (type id: 1038).

    QVariant::save: unable to save type 'QList<int>' (type id: 1038).

    QVariant::load: unable to load type 1038.
    QVariant::load: unable to load type 1038.
    QVariant::save: unable to save type 'QList<int>' (type id: 1038).

    QVariant::save: unable to save type 'QList<int>' (type id: 1038).

    QVariant::load: unable to load type 1038.
    QVariant::load: unable to load type 1038.
    Just out of curiosity, I thought I would try loading/saving my settings in a different way by using QVariantList. Thus, for loading my settings, I have something like:

    Qt Code:
    1. void CellmlAnnotationViewWidget::loadSettings(QSettings *pSettings)
    2. {
    3. // Retrieve the sizes of our editing widget and of its metadata details
    4. // Note: we would normally do this in CellmlAnnotationViewEditingWidget, but
    5. // we have one instance of it per CellML file and we want to share
    6. // some information between the different instances, so we have to do
    7. // it here instead...
    8.  
    9. QVariantList defaultEditingWidgetSizes = QVariantList() << 0.25*qApp->desktop()->screenGeometry().width()
    10. << 0.75*qApp->desktop()->screenGeometry().width();
    11. QVariantList defaultMetadataDetailsWidgetSizes = QVariantList() << 0.25*qApp->desktop()->screenGeometry().height()
    12. << 0.25*qApp->desktop()->screenGeometry().height()
    13. << 0.50*qApp->desktop()->screenGeometry().height();
    14.  
    15. QVariantList editingWidgetSizes = pSettings->value(SettingsCellmlAnnotationViewEditingWidgetSizes, defaultEditingWidgetSizes).toList();
    16. QVariantList metadataDetailsWidgetSizes = pSettings->value(SettingsCellmlAnnotationViewMetadataDetailsWidgetSizes, defaultMetadataDetailsWidgetSizes).toList();
    17.  
    18. foreach (const QVariant &editingWidgetSize, editingWidgetSizes)
    19. mEditingWidgetSizes << editingWidgetSize.toInt();
    20.  
    21. foreach (const QVariant &metadataDetailsWidgetSize, metadataDetailsWidgetSizes)
    22. mMetadataDetailsWidgetSizes << metadataDetailsWidgetSize.toInt();
    23. }
    To copy to clipboard, switch view to plain text mode 

    while for saving them, I have something like:

    Qt Code:
    1. void CellmlAnnotationViewWidget::saveSettings(QSettings *pSettings) const
    2. {
    3. // Keep track of the sizes of our editing widget and of its metadata details
    4.  
    5. QVariantList editingWidgetSizes = QVariantList();
    6. QVariantList metadataDetailsWidgetSizes = QVariantList();
    7.  
    8. foreach (const int &editingWidgetSize, mEditingWidgetSizes)
    9. editingWidgetSizes << editingWidgetSize;
    10.  
    11. foreach (const int &metadataDetailsWidgetSize, mMetadataDetailsWidgetSizes)
    12. metadataDetailsWidgetSizes << metadataDetailsWidgetSize;
    13.  
    14. pSettings->setValue(SettingsCellmlAnnotationViewEditingWidgetSizes, editingWidgetSizes);
    15. pSettings->setValue(SettingsCellmlAnnotationViewMetadataDetailsWidgetSizes, metadataDetailsWidgetSizes);
    16. }
    To copy to clipboard, switch view to plain text mode 

    Now, the interesting bit is that... it works on Windows, OS X and... also Linux! So, could it be that I have just come across a bug with Qt (5.2.1) on Linux?...

    Whatever the case, even though using QVariantList does indeed 'fixes' my problem, I would rather use my original approach, if possible (I find 'cleaner'). This aside, I am curious as what I have done wrong, if anything, in my original approach. Anyone?

    Cheers, Alan.

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Serialising QList<int> with QSettings

    Hmm. Can you check if QMetaType::save/load work for your type?

    Cheers,
    _

  3. #3
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Serialising QList<int> with QSettings

    Ok, I have just tested using the following code:

    Qt Code:
    1. int id = QMetaType::type("QList<int>");
    2.  
    3. if (id == QMetaType::UnknownType) {
    4. std::cout << ">>> Unknown type!?" << std::endl;
    5. } else {
    6. QList<int> data = QList<int>() << 3 << 5 << 7;
    7. QList<int> readData = QList<int>();
    8.  
    9. QByteArray byteArray;
    10. QDataStream dataStream(&byteArray, QIODevice::WriteOnly);
    11. QDataStream readDataStream(&byteArray, QIODevice::ReadOnly);
    12.  
    13. QMetaType::save(dataStream, id, &data);
    14. QMetaType::load(readDataStream, id, &readData);
    15.  
    16. bool error = false;
    17.  
    18. if (data.size() != readData.size()) {
    19. std::cout << ">>> data.size() != readData.size()" << std::endl;
    20. std::cout << " " << data.size() << " vs. " << readData.size() << std::endl;
    21.  
    22. error = true;
    23. } else {
    24. for (int i = 0, iMax = data.size(); i < iMax; ++i)
    25. if (data[i] != readData[i]) {
    26. std::cout << ">>> data[" << i << "] != readData[" << i << "]" << std::endl;
    27. std::cout << " " << data[i] << " vs. " << readData[i] << std::endl;
    28.  
    29. error = true;
    30.  
    31. break;
    32. }
    33. }
    34.  
    35. if (!error)
    36. std::cout << ">>> Everything went fine..." << std::endl;
    37. }
    To copy to clipboard, switch view to plain text mode 

    and I got:

    >>> Everything went fine...
    on Windows, OS X and Linux. So, as far as I can tell, QMetaType::save/load works fine for my QList<int> type.

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Serialising QList<int> with QSettings

    I had a quick look into the code and it seems to be more a limitation of the format rather than the platform.

    When writing the content to an INI file, the code checks for QStringList or QVariantList and serializes that into a list.
    Anything else is serialized as a string.

    So the stream operators are not used at all.

    You could try to register a converter (QMetaType::registerConverter) that serializes the list into a string.
    Not sure if the same trick works the other way around though.

    Cheers,
    _

  5. #5
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Serialising QList<int> with QSettings

    Quote Originally Posted by anda_skoa View Post
    I had a quick look into the code and it seems to be more a limitation of the format rather than the platform.

    When writing the content to an INI file, the code checks for QStringList or QVariantList and serializes that into a list.
    Anything else is serialized as a string.

    So the stream operators are not used at all.
    I must confess that I haven't checked the code, but... how would you explain that it works fine on Windows and OS X, but not on Linux?
    Last edited by agarny; 26th February 2014 at 09:14.

  6. #6
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Serialising QList<int> with QSettings

    Quote Originally Posted by agarny View Post
    I must confess that I haven't checked the code, but... how would you explain that it works fine on Windows and OS X, but not on Linux?
    My guess was that you were not using the IniFormat on all platforms, e.g. using NativeFormat everywhere which would be IniFormat only on non-Mac Unix.
    But if you are using IniFormat on all platforms then this is certainly weird and a bug.

    Cheers,
    _

  7. #7
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Serialising QList<int> with QSettings

    Quote Originally Posted by anda_skoa View Post
    My guess was that you were not using the IniFormat on all platforms, e.g. using NativeFormat everywhere which would be IniFormat only on non-Mac Unix.
    But if you are using IniFormat on all platforms then this is certainly weird and a bug.
    I had forgotten that QSettings can be used with different formats. I personally use the default format, i.e. NativeFormat, but I thought I would try with IniFormat. I did my testing on OS X and, as on Linux, my settings don't get loaded/saved 'properly'. Keeping in mind what you said about "the code [checking] for QStringList or QVariantList and [serializing] that into a list. Anything else [being] serialized as a string", it now all makes sense.

    So, everything works as expected. As for my code, I just ended up using QVariantList rather than QList<int>, and now everything works fine on all three platforms.

Similar Threads

  1. Replies: 1
    Last Post: 14th January 2011, 11:57
  2. Replies: 4
    Last Post: 20th August 2010, 13:54
  3. Replies: 2
    Last Post: 2nd September 2009, 13:36
  4. serialising reading writing
    By TheKedge in forum General Programming
    Replies: 4
    Last Post: 5th April 2007, 17:17
  5. QVariant, QList, QSettings
    By TheKedge in forum Qt Programming
    Replies: 6
    Last Post: 6th March 2007, 15:50

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.