Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to save/pickle Qt object's state



  • Hi,
    I actually didn't find much about that online, so here is the question.

    I would like to save the exact state on an object that is a reimplementation of a Qt class (in my case QGraphicsView, QGraphicsItems, etc.). I tried to pickle it, but all I get is an error

    TypeError: can't pickle PySide2.(...) objects
    

    I assume this has to do with the fact that these qt classes are implemented in c++. But I wouldn't assume it to be impossible since all the standard an object's current state describing methods like __dict__ etc. work, but I don't have a lot of experience in doing stuff like that.
    Is there a convenient way to save a qt object's state somehow to be able to reload it later? (PySide2)
    Thanks for answers!


  • Banned

    Okay from my understanding dealing with pickling for Pipes one can only pickle basic data types (str, int, real, bool) and dictionary/lists made up of these basic data types. As soon as one gets a more complex aspect associated with it one can no longer pickle it -- one could however extract the basic data types and pickle those and then use those to rebuild the more complex type.

    Still if you are using a database or even a config file in association with your program I would store these values there. For a database you can simply use sqlite3 and for config file I would suggest storing that in JSON but ultimately choose whatever you feel most comfortable with



  • Thank you, but that wasn't really the question.
    From what I know, pickle should normally be able to 'pickle' all types that derive from python's object class, which isn't the case here.
    That doesn't mean it's not possible to do the same. It will probably come down to the fact, that Qt's c++ classes are partially not 'picklable' (how should one store a QColor() pointer f.ex.) so storing the values of the members probably isn't possible. But I don't know, maybe there is a way.


  • Banned

    Okay not sure what you are doing then but when I delved into Pickling with Pipes (which may be different than your pickling) you could not actually pickle a QObject or anything derived from that because its not a basic data type. So if you are able to pickle any of these QObject (such just QObject) then yeah you are dealing with a different version of Pickle than I am playing with.

    Next how should one store a QColor() pointer for example --- I answer this by saying how do you make the QColor pointer that you are wanting to store aka what do you need to create that object from scratch -- these are the values you store and perhaps (if you want to make it generic) you store and indicator to the type of QObject you are storing then you can grab all these elements and then create them all via a generic bit of code putting them all into a dictionary that you can then access the object from within your code. This would make the process fairly simple and straight forward I would think but what do you think?


  • Lifetime Qt Champion

    Hi,

    @Niagarer said in How to save/pickle Qt object's state:

    Thank you, but that wasn't really the question.
    From what I know, pickle should normally be able to 'pickle' all types that derive from python's object class, which isn't the case here.
    That doesn't mean it's not possible to do the same. It will probably come down to the fact, that Qt's c++ classes are partially not 'picklable' (how should one store a QColor() pointer f.ex.) so storing the values of the members probably isn't possible. But I don't know, maybe there is a way.

    This is just an educated guess but for one thing QObject based classes cannot be copied. However, not all Qt classes derived from QObject. QColor, to take your example, is such a class and is usually not allocated on the heap so I wouldn't be surprised that pickle might work on it. But I have not tested it yet.

    Therefore, for QObject based classes, a "clone" method is the usual way to do it in C++ when one would like a second object with the same properties. In case of pickling, like was already suggested, pickling the properties and creating a new object on the other side will likely be the simpler approach.


  • Banned

    fcarney 22 May 2019, 16:29
    Pickling is serializing an object. Are you intending to reproduce an object by serializing its pointer? If so, then you are not going to get what you expect. A pointer points to a memory location and is only useful on the system it was created
    

    I found this on this forum which @SGaist was involved in ;) -- So if what is being said here is true to this situation then I do not think you are doing what you think you are doing when you are pickling a reference to an object. Again if this applies to this situation what you are pickling is a simple data type (aka a number) which is the address reference to the object you are wanting to pickle and not the object itself -- which means it would be worthless to use to try and recreate the object since upon restarting the program all those references would not be pointing to what you want them to be pointing to.

    However please, if I am missing the mark on this about what you are trying to do versus what you are doing do let me know I find this to be a rather interesting pickle -- pun intended ;)



  • @SGaist
    Hi,
    I'm sorry, I think I don't understand. Isn't that actually the problem, having to save property types that cannot be 'saved'? QColor actually does work, by the way, you are right, bad example by me :)
    For example, if I wanted to somehow save or copy or clone (whatever) a QGraphicsScene, I would also have to save the QGraphicsItems and Widgets, etc. placed in it. I am not aware of a way to save their states neither with pickle nor with JSON or something like that. If it is impossible to save these objects (like in a file), is there a way to clone them in PySide2 so that I can switch out my different versions of my scene for example later?


  • Lifetime Qt Champion

    That's up to you to implement the "cloning" or streaming of properties you want or need to get to the other side.



  • @Niagarer
    To save & reload a gfx scene, I json-ize out the hierarchy with class names and whatever attributes I know the user/code has been allowed to change, which I am in control of; enough to allow me to reconstruct. If I had to do all properties, it would be quite a bit of code. It's not what you would like, but as far as I know it's what you have to do.


Log in to reply