Solved Saving the whole application state( ```QTableWidget```, ```QPushButton```, ```QProcess```, objects created with ```new```)
-
No, no.
QObject
s are not serializable by themselves. You are not going to find a straightforward and simple solution to what you're looking for. You must write your own code, handling your own use case. -
@hbatalha
Unfortunately I think not :( But note that I have not tried this --- have you? I cannot imagine that any Qt model is serializable, so what doesQVariant::fromValue(ui->tableWidget->model())
actually produce?So, unless that works (please tell me if it does!), I meant it is your job to iterate all the rows/columns saving whatever data role values you have stored in it, such that you can reconstruct the model when you deserialize that data. The issue of storing the serialization on a
QSettings
is a detail. One possibility would be to save the data as JSON in a single setting's key's value. -
@JonB said
So, unless that works (please tell me if it does!)
Yes it "works", it does save some values in the ini file, but don't know what they mean nor how I can load from that as I can't convert
QVariant
toQAbstractItemModel*
. -
Yes it "works", it does save some values in the ini file
I really don't think it does (i.e. save the table contents/info)! And nor does @kshegunov. What exactly does that line produce? If it's a few bytes long, it can't possibly be the necessary information to reconstruct :)
-
-
@hbatalha
The way I said! You have to save what you want from the model with your own code. There isn't a magic wand. Both of us are telling you that! But doing it this way is likely to be a lot easier than actually trying to serialize a model or a widget with all its properties/attributes etc. as an object. -
@JonB
I don't think it does neither. That's why I had 'works' in quotes. What I meant is that it compiles and save some stuff in the file. And then I saw that the application informs that it can't saveQAbstractItemModel*
This is what it saves to the file App.ini:
[General] TableModel=@Variant(\0\0\0\x7f\0\0\0\x14QAbstractItemModel*\0)
-
@hbatalha
Yes, that is what I/ @kshegunov expected. All it's serializing is the pointer value with its type name! Because that's all it knows how to do. And will never get further, you have to write the code to serialize/save the data in the model, and to restore it. Which I think is easier than trying to serialize/save the widgets/the visible table for restoration. -
@JonB said
The way I said! You have to save what you want from the model with your own code. There isn't a magic wand. Both of us are telling you that! But doing it this way is likely to be a lot easier than actually trying to serialize a model or a widget with all its properties/attributes etc. as an object.
yeah, I already thought about a way to do that, it requires me to change a lot of working code but that seems to be the way to do it. I will get back to you once I finish.
-
I am happy to inform that I have achieved the goal stated in the OP.
What I did was create a function that that stores all the instances info in the
QSettings
and another function that will will create all the rows in theQTableWIdget
from the info saved.Something like this:
void saveSetting() { QSettings qsettings(QSettings::IniFormat, QSettings::UserScope, "Company", "APP"); qsettings.beginWriteArray("Table"); qsettings.remove(""); qsettings.endArray(); qsettings.beginWriteArray("Table"); for(qsizetype i = 0, len = vector_to_hold_FooClass_instances.size(); i < len; ++i) { qsettings.setArrayIndex(i); qsettings.setValue("args", vector_to_hold_FooClass_instances.at(i)->getArgs()); // I replaced the statuses with enum class instead of using ``bool`` // I couldn't find a better t save enum class to QSettings so I used this workaround qsettings.setValue("status", static_cast<int>(vector_to_hold_FooClass_instances.at(i)->status)); } qsettings.endArray(); }
and on loading:
void MainWindow::loadSettings() { QSettings qsettings(QSettings::IniFormat, QSettings::UserScope, "HBatalha", "Table"); int size = qsettings.beginReadArray("Table"); for(int i = 0; i < size; ++i) { QStringList args = qsettings.value("args").toString().split(" "); FooClass::Status status = static_cast<FooClass::Status>(qsettings.value("status").toInt()); const int dest_row = ui->tableWidget->rowCount(); ui->tableWidget->setRowCount(dest_row + 1); QPushButton* button1 = new QPushButton(); pause_button1->setIcon(QIcon(QPixmap(":/Icons/Icons/icon1.png"))); QPushButton* button2= new QPushButton(); cancel_button->setIcon(QIcon(QPixmap(":/Icons/Icons/icon2.png"))); ui->tableWidget->setItem(dest_row, 0, new QTableWidgetItem("Text1"); ui->tableWidget->setItem(dest_row, 1, new QTableWidgetItem("Text2")); ui->tableWidget->setCellWidget(dest_row, 2, button1 ); ui->tableWidget->setCellWidget(dest_row, 3, button2); FooClass *foo_class = new FooClass(args); foo_class->status = status; connect(button1, SIGNAL(clicked(bool)), this, SLOT(someTask(bool))); connect(button2, SIGNAL(clicked()), foo_class , SLOT(sometask())); connect(cancel_button, &QPushButton::clicked, [this, button1, button2, args]() // some code }); vector_to_hold_FooClass_instances.push_back(foo_class ); QSring arg = args.join(" "); QMap_args_rows[dest_row] = arg; foo_class->start(); args.clear(); } qsettings.endArray(); }
What do you guys think?