Save QTreeView/QStandardItemModel with DataStream to file?
-
@StudentScripter
You save your tree as a flat array, then you loose any parent/child relationship. -
@JonB said in Save QTreeView/QStandardItemModel with DataStream to file?:
I would suggest you consider saving your data as either XML or JSON.
That would encapsulate the tree structure. personally I don't like the idea of a binary data stream with some "markers" you have tried to put in it as "separators". You seem to be only saving string data from your model anyway. Perhaps a touch more initial work, easier to work with in the long run. Don't forget that if you get one thing wrong in binary data it's basically non-recoverable, XML/JSON is easily addressed in a text correction if required.
-
@JonB Well but if i have doesn't xml files i can't load/save a projectfile. I want a binary file with all data in it so it functions as a project file. Also i need to save: EditRole, CheckStateRole, DecorationRole, a few UserRoles.
-
@StudentScripter
The principle to save/load a binary tree is always the same.
Starting with the root item, for each item you need to:- save its data
- save the nb of children
- save the children items ( looks like we have some recursion here)
For loading, you have to reverse the process:
- create a item
- set its data
- get the nb of children
- create the children ( recursion again)
-
@mpergand Yes i really appreciate your answer, but that wasn't actually the point of my question yet. I just wanted to know: how do differentiate data within a binary?
How can i determine till where to read the data for my graphicsscene and where to start reading the data for my qtreeview?
Or to formulate it different:
Lets say I add an String named "MARKER" into my datastream and write this string to file. I want the datastream to search for this string and only read data after this string. -
@StudentScripter
Your are talking about two different objects, a graphic scene and a treeview and you seems to save their data to the same file, maybe saving them to two separate files may be a solution ? -
@mpergand No it has to be the same file, because i want to able to load from one projectfile. I found that using a qint32 as marker works. First i wanted to use a string but somehow qdatastreams to be unable to find a qstring.
Here is what i've done: (This works)
void ViewLayerList::saveTreeView(QString &filename) { qDebug() << "SaveAction TreeView"; QFile file(filename); if(!file.open(QIODevice::WriteOnly | QIODevice::Append)) return; QDataStream dataStream(&file); dataStream << qint32(0xDEADBEEF); // Write a separator or marker to indicate the end of the first data set int rowCount = model->rowCount(); dataStream << rowCount; for(int row = 0; row < rowCount; row++) { //dataStream << model->item(row, 1)->text(); } file.close(); } void ViewLayerList::loadTreeView(QString &filename) { qDebug() << "LoadAction TreeView"; // File laden und öffnen QFile file(filename); if (!file.open(QIODevice::ReadOnly)) return; QDataStream dataStream(&file); while (!dataStream.atEnd()) { qint32 test; dataStream >> test; if (test == qint32(0xDEADBEEF)) { qDebug() << "Marker Found"; break; // Exit the loop after finding the marker } } if (dataStream.atEnd()) { qDebug() << "Error: Marker not found or end of file reached"; file.close(); return; } // 11. Data in dem File int rowCount; dataStream >> rowCount; for(int row = 0; row < rowCount; row++) { QStandardItem *w_item = new QStandardItem(); model->setItem(row, 0, w_item); } file.close(); }
-
@StudentScripter
You can use a QBuffer instead.
Save your data to two separate buffers, then save them to a file with at the start of the file, the offset of the second buffer where it is located in the file. -
@mpergand
Just "yuck", and asking for trouble! I'm sure you know this.@StudentScripter said in Save QTreeView/QStandardItemModel with DataStream to file?:
@JonB Well but if i have doesn't xml files i can't load/save a projectfile. I want a binary file with all data in it so it functions as a project file. Also i need to save: EditRole, CheckStateRole, DecorationRole, a few UserRoles
None of this is relevant. And I don't know how a "binary file" would function as a "project file". Anyway, best of luck.
-
@mpergand
One can, but I wouldn't recommend it for a newcomer. And it's just unnecessary here when the data format is the OP's own choice and XML/JSON sounds like it would be fine/more suitable. As well as happening to make the "include this data separately from that data" easier. But anyway I think the OP wants to do binary way, that's fine. -
-
@StudentScripter
As an alternative, you can serialize your buffers as an array of QByteArray. -
@StudentScripter
Each application may save its settings or whatever is whichever format it pleases. I would not know whether your particular apps store in one format or another. If it's your decision to save binary, that's fine. -
@StudentScripter from what you are writing, it seems that you want to be able to store stuff in a random order and then stream them back again from that random order.
Currently there are several formats that are in fact compressed files containing several other files. Take the various office files format for example: one archive containing several files.
That said, the simple way to do it is what I wrote: you always store and load your stuff in the same order.
The more complex way is what my fellows proposed: one file per element. That way you can stream whatever you want independently.
-
@SGaist said in Save QTreeView/QStandardItemModel with DataStream to file?:
it seems that you want to be able to store stuff in a random order and then stream them back again from that random order.
In this case one can use QMap to identify data by its name without any order.
I talked about that HERE -
@JonB Well as i found out may your XML approach seems to be a better pratice as i found out that .docx for example is just a renamed .zip archive with xml files in it.
In this case: do you know how to create such an archive containing xml files and how to read from that archive using Qt C++? Haven't found a topic on doing this in a zip like archive. -
-
@StudentScripter
:) Either XML (more feature-rich) or JSON (simpler) could be used for storing information. You still have to decide what to put into it and what to create when reading back out of it. They are just text files with a certain format.Qt offers support for either. Start from https://doc.qt.io/qt-6/qtxml-module.html and the
QDomDocument
for a full-featured, in-memory XML structure; lower-levelXMLStreamWriter/Reader
classes, https://doc.qt.io/qt-6/qxmlstreamwriter.html, could be used if you want to write code to just write/read a stream without memory overhead. I suspect you would want theQDocument
. Or https://doc.qt.io/qt-6/json.html is where to start from for JSON support.I'm afraid it is still down to you to write the code to decide what to put into the file and how to restore it. But as I said earlier, you won't be able to stream
QTreeView
orQStandardItemModel
viaQDataStream
because they are both derived fromQObject
and that cannot be serialized. So you would still have to make the same choices there as to what/how to save/restore.The "zipping like an archive" is just an optional extra at the end. It does not materially affect anything. I suggest you get your serializing sorted out before worrying about that aspect.