Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How do I properly serialize and deserialize a QList class in QT using QDatastream?

How do I properly serialize and deserialize a QList class in QT using QDatastream?

Scheduled Pinned Locked Moved Solved General and Desktop
29 Posts 5 Posters 6.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    twodee
    wrote on last edited by
    #1

    I am trying to serialize a custom class Layer* and read it back using QDataStream. Now, Layer is an abstract class with virtual method which is inherited by different kinds of layers: RasterLayer, TextLayer, AdjustmentLayer etc.

    I have a QList<Layer*> layers which keeps track of all the layers, and any adjustments made to a layer are updated in the list. I need to serialize and deserialize the QList to its original state and restore the properties of the individual layers (of different types).

    Here is layer.h:

    #ifndef LAYER_H
    #define LAYER_H
    
    #include <QString>
    #include <QImage>
    #include <QDebug>
    #include <QListWidgetItem>
    #include <QGraphicsItem>
    #include <QPixmap>
    
    class Layer : public QListWidgetItem
    {
    
    public:
    
        enum LayerType{
            RASTER,
            VECTOR,
            TEXT,
            ADJUSTMENT
        };
    
        Layer(QString name, LayerType type);
    
        ~Layer();
        inline void setName(QString &name) { _name = name; }
        inline QString getName() { return _name; }
        inline LayerType getType() { return _type; }
    
        virtual void setSceneSelected(bool select) = 0;
        virtual void setLayerSelected(bool select) = 0;
        virtual void setZvalue(int z) = 0;
        virtual void setParent(QGraphicsItem *parent) = 0;
    
    protected:
        QString _name;
        LayerType _type;
    };
    
    #endif // LAYER_H
    

    This is extended by a RasterLayer class:

    #ifndef RASTERLAYER_H
    #define RASTERLAYER_H
    
    #include <QGraphicsPixmapItem>
    #include <QPainter>
    #include <QGraphicsScene>
    
    #include "layer.h"
    
        class RasterLayer : public Layer, public QGraphicsPixmapItem
        {
        public:
            RasterLayer(const QString &name, const QImage &image);
            RasterLayer();
            ~RasterLayer();
        
            void setLocked(bool lock);
            void setSceneSelected(bool select);
            void setLayerSelected(bool select);
            void setZvalue(int z);
            void setParent(QGraphicsItem *parent);
            inline QPixmap getPixmap() const { return pixmap(); }
            inline QPointF getPos() const { return QGraphicsPixmapItem::pos(); }
            inline void setLayerPos(QPointF pos) { setPos(pos);}
            inline void setLayerPixmap(QPixmap pixmap) { setPixmap(pixmap); }
        
            friend QDataStream& operator<<(QDataStream& ds, RasterLayer *&layer)
            {
                ds << layer->getPixmap() << layer->getName() << layer->getPos();
                return ds;
            }
        
            friend QDataStream& operator>>(QDataStream& ds, RasterLayer *layer)
            {
                QString name;
                QPixmap pixmap;
                QPointF pos;
        
                ds >> pixmap >> name >> pos;
        
                layer->setName(name);
                layer->setPixmap(pixmap);
                layer->setPos(pos);
        
                return ds;
            }
        
        protected:
            void paint(QPainter *painter,
                       const QStyleOptionGraphicsItem *option,
                       QWidget *widget);
        
        private:
            QImage _image;
        };
        
        #endif // RASTERLAYER_H
    

    I am currently trying to test serialization-deserialization of a RasterLayer like this:

    QFile file(fileName);
    
    file.open(QIODevice::WriteOnly);
    QDataStream out(&file);
    
    Layer *layer = paintWidget->getItems().at(1);
    // Gets the second element in the list
    
    RasterLayer *raster = dynamic_cast<RasterLayer*> (layer);
    out << raster;
    file.close();
    

    Now, as you can see here, I am specifically casting Layer* to a RasterLayer*to be serialized, and this works since I have worked on only one type of layer till now. So my first question is:

    How do I generalize this serialization process to all types of layers?

    Every type of layer will have a different way of serialization since each hold different properties. Also, the casting here feels like a bit of code smell and a possible bad design choice. So, having something like serialize the entire list of layers calling their corresponding overloaded operators would be the expected scenario.

    My second question is:

    How do I deserialize the data properly?
    Here's how I am currently serializing an individual RasterLayer:

    QFile newFile(fileName);
    newFile.open(QIODevice::ReadOnly);
    QDataStream in(&newFile);
    
    RasterLayer *layer2 = new RasterLayer;
    in >> layer2;
    paintWidget->pushLayer(layer2);
    ui->layerView->updateItems(paintWidget->getItems());
    

    Firstly, I don't think serializing to a pointer is something I should be doing in this case, but I am not sure what else to do or how to do better yet. Secondly, the deserialization works here, but it doesn't quite do what I would be expecting it to do. Although I am using setters in the overloaded operators, it's really not updating the layer properly. I need to call the constructor to make a new layer out of it.

    I have tried this: https://stackoverflow.com/questions/2570679/serialization-with-qt but I am not quite sure how to have a Layer* convert it to a Layer, serialize it, deserialize it and then convert it back to Layer*.
    So I need to add a third step:

    RasterLayer *layer3 = new RasterLayer(layer2->getName(), layer2->getPixmap().toImage());
    layer3->setPos(layer2->pos());
    

    and then push layer3 to the list to actually make it work. According to this post: https://stackoverflow.com/a/23697747/6109408, I really shouldn't be doing a new RasterLayer... inside the operator overloading function (or else I will fry in hell), and I am following the first suggestion given there, which isn't very much working in my case and I don't know the right way to do it.

    Also, how do I deserialize this for a general QList of Layer*s instead of having to create new specific layer instances and injecting them with deserialized data? Although this is similar: https://stackoverflow.com/questions/23202667/serialize-a-class-with-a-qlist-of-custom-classes-as-member-using-qdatastream#23219659, the answers weren't clear enough for me to understand.

    I have had an idea about an intermediate value holder class that I will use to serialize all sorts of Layers and let that create and inject the parameters depending upon the type of Layer it is, but I am not sure if that will work.

    Thanks for helping me out.

    JonBJ 1 Reply Last reply
    0
    • T twodee

      I am trying to serialize a custom class Layer* and read it back using QDataStream. Now, Layer is an abstract class with virtual method which is inherited by different kinds of layers: RasterLayer, TextLayer, AdjustmentLayer etc.

      I have a QList<Layer*> layers which keeps track of all the layers, and any adjustments made to a layer are updated in the list. I need to serialize and deserialize the QList to its original state and restore the properties of the individual layers (of different types).

      Here is layer.h:

      #ifndef LAYER_H
      #define LAYER_H
      
      #include <QString>
      #include <QImage>
      #include <QDebug>
      #include <QListWidgetItem>
      #include <QGraphicsItem>
      #include <QPixmap>
      
      class Layer : public QListWidgetItem
      {
      
      public:
      
          enum LayerType{
              RASTER,
              VECTOR,
              TEXT,
              ADJUSTMENT
          };
      
          Layer(QString name, LayerType type);
      
          ~Layer();
          inline void setName(QString &name) { _name = name; }
          inline QString getName() { return _name; }
          inline LayerType getType() { return _type; }
      
          virtual void setSceneSelected(bool select) = 0;
          virtual void setLayerSelected(bool select) = 0;
          virtual void setZvalue(int z) = 0;
          virtual void setParent(QGraphicsItem *parent) = 0;
      
      protected:
          QString _name;
          LayerType _type;
      };
      
      #endif // LAYER_H
      

      This is extended by a RasterLayer class:

      #ifndef RASTERLAYER_H
      #define RASTERLAYER_H
      
      #include <QGraphicsPixmapItem>
      #include <QPainter>
      #include <QGraphicsScene>
      
      #include "layer.h"
      
          class RasterLayer : public Layer, public QGraphicsPixmapItem
          {
          public:
              RasterLayer(const QString &name, const QImage &image);
              RasterLayer();
              ~RasterLayer();
          
              void setLocked(bool lock);
              void setSceneSelected(bool select);
              void setLayerSelected(bool select);
              void setZvalue(int z);
              void setParent(QGraphicsItem *parent);
              inline QPixmap getPixmap() const { return pixmap(); }
              inline QPointF getPos() const { return QGraphicsPixmapItem::pos(); }
              inline void setLayerPos(QPointF pos) { setPos(pos);}
              inline void setLayerPixmap(QPixmap pixmap) { setPixmap(pixmap); }
          
              friend QDataStream& operator<<(QDataStream& ds, RasterLayer *&layer)
              {
                  ds << layer->getPixmap() << layer->getName() << layer->getPos();
                  return ds;
              }
          
              friend QDataStream& operator>>(QDataStream& ds, RasterLayer *layer)
              {
                  QString name;
                  QPixmap pixmap;
                  QPointF pos;
          
                  ds >> pixmap >> name >> pos;
          
                  layer->setName(name);
                  layer->setPixmap(pixmap);
                  layer->setPos(pos);
          
                  return ds;
              }
          
          protected:
              void paint(QPainter *painter,
                         const QStyleOptionGraphicsItem *option,
                         QWidget *widget);
          
          private:
              QImage _image;
          };
          
          #endif // RASTERLAYER_H
      

      I am currently trying to test serialization-deserialization of a RasterLayer like this:

      QFile file(fileName);
      
      file.open(QIODevice::WriteOnly);
      QDataStream out(&file);
      
      Layer *layer = paintWidget->getItems().at(1);
      // Gets the second element in the list
      
      RasterLayer *raster = dynamic_cast<RasterLayer*> (layer);
      out << raster;
      file.close();
      

      Now, as you can see here, I am specifically casting Layer* to a RasterLayer*to be serialized, and this works since I have worked on only one type of layer till now. So my first question is:

      How do I generalize this serialization process to all types of layers?

      Every type of layer will have a different way of serialization since each hold different properties. Also, the casting here feels like a bit of code smell and a possible bad design choice. So, having something like serialize the entire list of layers calling their corresponding overloaded operators would be the expected scenario.

      My second question is:

      How do I deserialize the data properly?
      Here's how I am currently serializing an individual RasterLayer:

      QFile newFile(fileName);
      newFile.open(QIODevice::ReadOnly);
      QDataStream in(&newFile);
      
      RasterLayer *layer2 = new RasterLayer;
      in >> layer2;
      paintWidget->pushLayer(layer2);
      ui->layerView->updateItems(paintWidget->getItems());
      

      Firstly, I don't think serializing to a pointer is something I should be doing in this case, but I am not sure what else to do or how to do better yet. Secondly, the deserialization works here, but it doesn't quite do what I would be expecting it to do. Although I am using setters in the overloaded operators, it's really not updating the layer properly. I need to call the constructor to make a new layer out of it.

      I have tried this: https://stackoverflow.com/questions/2570679/serialization-with-qt but I am not quite sure how to have a Layer* convert it to a Layer, serialize it, deserialize it and then convert it back to Layer*.
      So I need to add a third step:

      RasterLayer *layer3 = new RasterLayer(layer2->getName(), layer2->getPixmap().toImage());
      layer3->setPos(layer2->pos());
      

      and then push layer3 to the list to actually make it work. According to this post: https://stackoverflow.com/a/23697747/6109408, I really shouldn't be doing a new RasterLayer... inside the operator overloading function (or else I will fry in hell), and I am following the first suggestion given there, which isn't very much working in my case and I don't know the right way to do it.

      Also, how do I deserialize this for a general QList of Layer*s instead of having to create new specific layer instances and injecting them with deserialized data? Although this is similar: https://stackoverflow.com/questions/23202667/serialize-a-class-with-a-qlist-of-custom-classes-as-member-using-qdatastream#23219659, the answers weren't clear enough for me to understand.

      I have had an idea about an intermediate value holder class that I will use to serialize all sorts of Layers and let that create and inject the parameters depending upon the type of Layer it is, but I am not sure if that will work.

      Thanks for helping me out.

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @twodee said in How do I properly serialize and deserialize a QList class in QT using QDatastream?:

      RasterLayer *raster = dynamic_cast<RasterLayer*> (layer);
      out << raster;

      Now, as you can see here, I am specifically casting Layer* to a RasterLayer*to be serialized, and this works since I have worked on only one type of layer till now

      While you are waiting for someone who can really help with your overall problem....

      Although I am not a C++-er, I don't think that dynamic cast makes a blind bit of difference. You might just as well have left it at:

      out << layer;

      As far as I know, dynamic_cast<> just does a run-time check on the type and returns the same pointer if it is of the specified class or nullptr if not. It changes nothing. And out << variable; just calls the variable's actual serialization operator, regardless of type.

      You might like to check this. If I'm right, you won't be able to use anything in that approach in the way you thought it worked. And if I'm wrong you can tell me so!

      T 1 Reply Last reply
      0
      • JonBJ JonB

        @twodee said in How do I properly serialize and deserialize a QList class in QT using QDatastream?:

        RasterLayer *raster = dynamic_cast<RasterLayer*> (layer);
        out << raster;

        Now, as you can see here, I am specifically casting Layer* to a RasterLayer*to be serialized, and this works since I have worked on only one type of layer till now

        While you are waiting for someone who can really help with your overall problem....

        Although I am not a C++-er, I don't think that dynamic cast makes a blind bit of difference. You might just as well have left it at:

        out << layer;

        As far as I know, dynamic_cast<> just does a run-time check on the type and returns the same pointer if it is of the specified class or nullptr if not. It changes nothing. And out << variable; just calls the variable's actual serialization operator, regardless of type.

        You might like to check this. If I'm right, you won't be able to use anything in that approach in the way you thought it worked. And if I'm wrong you can tell me so!

        T Offline
        T Offline
        twodee
        wrote on last edited by
        #3

        @JonB said in How do I properly serialize and deserialize a QList class in QT using QDatastream?:

        You might like to check this. If I'm right, you won't be able to use anything in that approach in the way you thought it worked. And if I'm wrong you can tell me so!

        Hi, thanks for your input. I tried this out and for some reason, if I directly use Layer nothing gets serialized (maybe a NULL value does) and none of the data gets written to the file. I have tried this earlier on, but gave it a try again swapping the datatypes of the overloaded operator from RasterLayer with Layer*, but it still doesn't seem to do the trick. I was hoping it would, but I think I am missing something here.

        JonBJ 1 Reply Last reply
        0
        • T twodee

          @JonB said in How do I properly serialize and deserialize a QList class in QT using QDatastream?:

          You might like to check this. If I'm right, you won't be able to use anything in that approach in the way you thought it worked. And if I'm wrong you can tell me so!

          Hi, thanks for your input. I tried this out and for some reason, if I directly use Layer nothing gets serialized (maybe a NULL value does) and none of the data gets written to the file. I have tried this earlier on, but gave it a try again swapping the datatypes of the overloaded operator from RasterLayer with Layer*, but it still doesn't seem to do the trick. I was hoping it would, but I think I am missing something here.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

          @twodee
          You seem to be talking about changing between pointers or not, that's not what I meant. And I trust you used your layer variable and not your Layer type (note the capitalizations, you must get that right, I did mean literally out << layer;). I'm surprised at your finding as now I don't understand how the cast could make any difference at runtime, but I'm not a C++ expert so we'll leave it at that. Sorry.

          T 1 Reply Last reply
          0
          • JonBJ JonB

            @twodee
            You seem to be talking about changing between pointers or not, that's not what I meant. And I trust you used your layer variable and not your Layer type (note the capitalizations, you must get that right, I did mean literally out << layer;). I'm surprised at your finding as now I don't understand how the cast could make any difference at runtime, but I'm not a C++ expert so we'll leave it at that. Sorry.

            T Offline
            T Offline
            twodee
            wrote on last edited by
            #5

            @JonB Yes, I did use my layer variable, I did comment out the raster part and that didn't seem to work. My findings look a bit odd to me as well, thanks for trying. :D

            1 Reply Last reply
            1
            • VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on last edited by VRonin
              #6

              The normal way to do it:

              • create 2 pure virtual protected members in Layer that takes a QDataStream& argument and saves/loads the layer from it
              • create QDataStream stream operators for Layer (not Layer*) that do nothing but calling those protected methods
              • serialise something that will tell you what kind of Layer it will be (something like QVariant::userType does)
              • serialise directly by dereferencing a Layer* no need to cast anything

              RasterLayer *layer2 = new RasterLayer; in >> *layer2; is perfectly valid, as long as paintWidget owns the allocated memory

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              T 1 Reply Last reply
              3
              • VRoninV VRonin

                The normal way to do it:

                • create 2 pure virtual protected members in Layer that takes a QDataStream& argument and saves/loads the layer from it
                • create QDataStream stream operators for Layer (not Layer*) that do nothing but calling those protected methods
                • serialise something that will tell you what kind of Layer it will be (something like QVariant::userType does)
                • serialise directly by dereferencing a Layer* no need to cast anything

                RasterLayer *layer2 = new RasterLayer; in >> *layer2; is perfectly valid, as long as paintWidget owns the allocated memory

                T Offline
                T Offline
                twodee
                wrote on last edited by
                #7

                @VRonin Hi, thanks for responding. I am getting this error which I usually can avoid using a const somewhere: error: passing ‘const RasterLayer’ as ‘this’ argument discards qualifiers [-fpermissive] : setName(name);

                As you can see in the layer.h, it is an inline method inline void setName(QString &name) { _name = name; } , what should I be doing in this case?

                1 Reply Last reply
                0
                • VRoninV Offline
                  VRoninV Offline
                  VRonin
                  wrote on last edited by
                  #8

                  Looks like you are deserialising on a const method. What is the code around that call?

                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                  ~Napoleon Bonaparte

                  On a crusade to banish setIndexWidget() from the holy land of Qt

                  T 2 Replies Last reply
                  0
                  • VRoninV VRonin

                    Looks like you are deserialising on a const method. What is the code around that call?

                    T Offline
                    T Offline
                    twodee
                    wrote on last edited by
                    #9
                    This post is deleted!
                    1 Reply Last reply
                    0
                    • VRoninV VRonin

                      Looks like you are deserialising on a const method. What is the code around that call?

                      T Offline
                      T Offline
                      twodee
                      wrote on last edited by
                      #10

                      @VRonin I figured the serialization out, now I have to do something like out << *layer; to get it serialized. But how will that allow me to serialize a QList<Layer*> to be serialized as a whole?

                      JonBJ 1 Reply Last reply
                      0
                      • T twodee

                        @VRonin I figured the serialization out, now I have to do something like out << *layer; to get it serialized. But how will that allow me to serialize a QList<Layer*> to be serialized as a whole?

                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote on last edited by JonB
                        #11

                        @twodee
                        Read through threadin this forum https://forum.qt.io/topic/58701/how-to-serialize-deserialize-a-qlist-myclass

                        As per http://doc.qt.io/qt-5/datastreamformat.html, QList<T> can be de/serialized. You need to provide the de/serialization for your class T, which is what you have been working on here.

                        1 Reply Last reply
                        0
                        • T Offline
                          T Offline
                          twodee
                          wrote on last edited by
                          #12
                          This post is deleted!
                          1 Reply Last reply
                          0
                          • T Offline
                            T Offline
                            twodee
                            wrote on last edited by twodee
                            #13

                            As the post said it's about one line with the operator new, could you tell me what that line is?

                             QList<Layer*> layers = paintWidget->getItems(); 
                            out << layers;
                            

                            This doesn't seem to do the trick. I have been scratching my head for too long, sorry if I am being stupid.

                            Also for some reason overloading QDataStream& operator<<(QDataStream& ds, const Layer *layer) doesn't work anymore, which did work earlier.

                            1 Reply Last reply
                            0
                            • VRoninV Offline
                              VRoninV Offline
                              VRonin
                              wrote on last edited by VRonin
                              #14
                              out << qint32(layers.size());
                              for(Layer* layer : qAsConst(layers))
                              out << qint32(layer->type()) << *layer;
                              

                              qint32 size;
                              qint32 type;
                              in >> size;
                              while(size-- >0 ){
                              in >> type;
                              Layer* layer = nullptr;
                              switch(type){
                              case Raster:
                              layer = new RasterLayer;
                              break;
                              default:
                              Q_UNREACHABLE();
                              }
                              in >> *layer;
                              }

                              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                              ~Napoleon Bonaparte

                              On a crusade to banish setIndexWidget() from the holy land of Qt

                              JonBJ T 2 Replies Last reply
                              0
                              • VRoninV VRonin
                                out << qint32(layers.size());
                                for(Layer* layer : qAsConst(layers))
                                out << qint32(layer->type()) << *layer;
                                

                                qint32 size;
                                qint32 type;
                                in >> size;
                                while(size-- >0 ){
                                in >> type;
                                Layer* layer = nullptr;
                                switch(type){
                                case Raster:
                                layer = new RasterLayer;
                                break;
                                default:
                                Q_UNREACHABLE();
                                }
                                in >> *layer;
                                }
                                JonBJ Offline
                                JonBJ Offline
                                JonB
                                wrote on last edited by JonB
                                #15

                                @VRonin
                                I don't want to muddy the waters for the OP here, but may I ask: why do you explicitly serialize the layers list yourself in a loop? I thought that the point of the link I mentioned, http://doc.qt.io/qt-5/datastreamformat.html, is that it shows:

                                The QDataStream allows you to serialize some of the Qt data types. The table below lists the data types that QDataStream can serialize

                                QList<T>	
                                    The number of items (quint32)
                                    The items (T)
                                

                                so why can't you just out << layers ?

                                Is this because you want to know where layer->type() is in the serialization, so that you can look at it during deserialization and do your own newing? If there were no sub-classing going on in the list elements then you wouldn't need to do that and could just do the list directly? Could it then just be deserialized with in >> layers? Or will deserializing never do any newing of elements for you?

                                VRoninV 1 Reply Last reply
                                0
                                • JonBJ JonB

                                  @VRonin
                                  I don't want to muddy the waters for the OP here, but may I ask: why do you explicitly serialize the layers list yourself in a loop? I thought that the point of the link I mentioned, http://doc.qt.io/qt-5/datastreamformat.html, is that it shows:

                                  The QDataStream allows you to serialize some of the Qt data types. The table below lists the data types that QDataStream can serialize

                                  QList<T>	
                                      The number of items (quint32)
                                      The items (T)
                                  

                                  so why can't you just out << layers ?

                                  Is this because you want to know where layer->type() is in the serialization, so that you can look at it during deserialization and do your own newing? If there were no sub-classing going on in the list elements then you wouldn't need to do that and could just do the list directly? Could it then just be deserialized with in >> layers? Or will deserializing never do any newing of elements for you?

                                  VRoninV Offline
                                  VRoninV Offline
                                  VRonin
                                  wrote on last edited by
                                  #16

                                  @JonB That would imply having datastream operators acting on pointers and that's dangerous:

                                  • What if you pass a null pointer
                                  • What if you pass a dangling pointer
                                  • Who own the memory allocated by the pointer? the operator?

                                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                  ~Napoleon Bonaparte

                                  On a crusade to banish setIndexWidget() from the holy land of Qt

                                  JonBJ 1 Reply Last reply
                                  0
                                  • VRoninV VRonin

                                    @JonB That would imply having datastream operators acting on pointers and that's dangerous:

                                    • What if you pass a null pointer
                                    • What if you pass a dangling pointer
                                    • Who own the memory allocated by the pointer? the operator?
                                    JonBJ Offline
                                    JonBJ Offline
                                    JonB
                                    wrote on last edited by
                                    #17

                                    @VRonin
                                    So are you saying: "Yes, you can de/serialize QList<T> directly as per that link, but while that's fine for simple types it's not suitable for pointers"?

                                    I may be confusing myself. In my C# we don't have "pointers" and we just de/serialize lists directly without a care. Deserializing does whatever newing is necessary behind the scenes.

                                    J.HilkJ 1 Reply Last reply
                                    0
                                    • JonBJ JonB

                                      @VRonin
                                      So are you saying: "Yes, you can de/serialize QList<T> directly as per that link, but while that's fine for simple types it's not suitable for pointers"?

                                      I may be confusing myself. In my C# we don't have "pointers" and we just de/serialize lists directly without a care. Deserializing does whatever newing is necessary behind the scenes.

                                      J.HilkJ Offline
                                      J.HilkJ Offline
                                      J.Hilk
                                      Moderators
                                      wrote on last edited by
                                      #18

                                      @JonB said in How do I properly serialize and deserialize a QList class in QT using QDatastream?:

                                      I may be confusing myself. In my C# we don't have "pointers" and we just de/serialize lists directly without a care.

                                      I beg to differ!

                                      you can use pointers in c# and manage your memory by hand, but you have to explicitly tell the compiler to allow it with -unsafe, IIRC

                                      Quick google search:
                                      https://www.tutorialspoint.com/csharp/csharp_unsafe_codes.htm


                                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                      Q: What's that?
                                      A: It's blue light.
                                      Q: What does it do?
                                      A: It turns blue.

                                      JonBJ 1 Reply Last reply
                                      0
                                      • VRoninV Offline
                                        VRoninV Offline
                                        VRonin
                                        wrote on last edited by
                                        #19

                                        take this example:

                                        // QList<int*> m_ownerList;
                                        m_ownerList.append(new int(5));
                                        m_ownerList.append(new int(3));
                                        
                                        m_myInt1 = new  int(5);
                                        m_myInt2 = new  int(3);
                                        m_nonOwnerList = QList<int*>{{m_myInt1 ,m_myInt2} };
                                        

                                        What should QDataStream& operator>>(QDataStream& , const QList<int*> ) do? free the memory already allocated or not?

                                        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                        ~Napoleon Bonaparte

                                        On a crusade to banish setIndexWidget() from the holy land of Qt

                                        1 Reply Last reply
                                        0
                                        • J.HilkJ J.Hilk

                                          @JonB said in How do I properly serialize and deserialize a QList class in QT using QDatastream?:

                                          I may be confusing myself. In my C# we don't have "pointers" and we just de/serialize lists directly without a care.

                                          I beg to differ!

                                          you can use pointers in c# and manage your memory by hand, but you have to explicitly tell the compiler to allow it with -unsafe, IIRC

                                          Quick google search:
                                          https://www.tutorialspoint.com/csharp/csharp_unsafe_codes.htm

                                          JonBJ Offline
                                          JonBJ Offline
                                          JonB
                                          wrote on last edited by
                                          #20

                                          @J.Hilk
                                          But I would never want to use pointers in C# or manage memory by hand, that's (more than) half the point of using C#!?

                                          Maybe there's a misunderstanding. I don't use C# with Qt (I use Python). I'm just familiar with C# compared to C++. I am trying to understand @VRonin's explanation of de/serializing this QList<T>, where he is saying he does it explicitly to manage pointers, when I know I would just de/serialize a list from C# without iterating the elements myself, and trying to understand why.

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved