How to deserialize a QMap<int,QVariant> ?



  • Hello!

    I need help deserializing a map that has QVariants as values...

    I use the following code to serialize it:

    void MyClass::SetMessageDataFromMap(QMap<int, QVariant> &myMap, QByteArray &myData)
    {
    
        QDataStream oMessageDataStream(&myData,QIODevice::WriteOnly);
    
        oMessageDataStream << myMap;    
    
    }
    

    I say it seems to work because I seem to see some data in the corresponding variable when I look at it in the debugger after serialization. However, I'm not sure if the data is correct, or is it just gibberish.

    I use the following code to deserialze the map:

    void MyClass::GetMessageDatatoMap(QMap<int, QVariant> &myMap, QByteArray &myData)
    {
    
      QDataStream in (&myData,QIODevice::ReadOnly);
      in >> myMap;
    
    }
    

    When I searched Google for the answer, I found that QVariant serialization isn't supported 'out of the box'. So I would appreciate any pointers to how I should go about serializing and deserializing QMap<int, QVariant> or even if such practice is advisable at all.



  • @Mike-Fidel Hi.
    Hm... Its work for me.

    #include "mainwindow.h"
    #include <QApplication>
    #include "QDebug"
    
    template<typename T>
    void writeData(T &val, QByteArray &out) {
        QDataStream in(&out, QIODevice::WriteOnly);
        in << val;
    }
    
    template<typename T>
    void readData(T &val, QByteArray &data) {
        QDataStream out(&data, QIODevice::ReadOnly);
        out >> val;
    }
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QMap<int, QVariant> mpWrite;
        mpWrite.insert(1, "taz");
        mpWrite.insert(2, 2);
        mpWrite.insert(3, 3.2);
    
        QByteArray writeBuff;
        writeData(mpWrite, writeBuff);
    
        QMap<int, QVariant> mpRead;
        readData(mpRead, writeBuff);
    
        for (const auto &it : mpRead) {
            qDebug() << it;
        }
        //Result is
        //QVariant(QString, "taz")
        //QVariant(int, 2)
        //QVariant(double, 3.2)
    
        MainWindow w;
        w.show();
    
        return a.exec();
    }
    
    

    You can use QVariant here to deserialize it.
    What types are in QVariant back? Only primitive types(int, double, QString etc..) or your custom Class?



  • @Mike-Fidel said in How to deserialize a QMap<int,QVariant> ?:

    When I searched Google for the answer, I found that QVariant serialization isn't supported 'out of the box'.

    ? http://doc.qt.io/qt-5/datastreamformat.html describes how QVariant is supported for serialization, so correspondingly you can deserialize.

    Alternatively, you can also do a QVariant via JSON.



  • @Taz742 said in How to deserialize a QMap<int,QVariant> ?:

    Thank you! It does work indeed. Turns out, I had a bug elsewhere... Thank you for your time.

    For anyone else wondering, This works exactly like @Taz742 said!



  • @Mike-Fidel Good!
    If you have a number of functions that you use to write or read different types of data, use the template <> as you have seen in the example. Because it will save you a lot of time!

    Something like static function.

    #include "mainwindow.h"
    #include <QApplication>
    #include "QDebug"
    
    class MyStreamOperators {
        public:
            template<typename T>
            static void writeData(T &val, QByteArray &out) {
                QDataStream in(&out, QIODevice::WriteOnly);
                in << val;
            }
    
            template<typename T>
            static void readData(T &val, QByteArray &data) {
                QDataStream out(&data, QIODevice::ReadOnly);
                out >> val;
            }
    };
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QMap<int, QVariant> mpWrite;
        mpWrite.insert(1, "taz");
        mpWrite.insert(2, 2);
        mpWrite.insert(3, 3.2);
    
        QByteArray writeBuff;
        MyStreamOperators::writeData(mpWrite, writeBuff);
    
        QMap<int, QVariant> mpRead;
        MyStreamOperators::readData(mpRead, writeBuff);
    
        for (const auto &it : mpRead) {
            qDebug() << it;
        }
        //Map example End. ///////////////////////////////////////////////////////
    
    
        QVector<int> vectorToWrite = {1, 2, 3, 4, 5};
        QByteArray writeVectorBuff;
        MyStreamOperators::writeData(vectorToWrite, writeVectorBuff);
    
        QVector<int> vectorToRead;
        MyStreamOperators::readData(vectorToRead, writeVectorBuff);
    
        for (const auto &it : vectorToRead) {
            qDebug() << it;
        }
        //Vector example End. ///////////////////////////////////////////////////////
    
    
        return a.exec();
    }
    
    

    And dont forget to mark this topic to SOLVED. Thank :)



  • @Taz742 Thank you for the tip!