I am going to save a struct in a binary file and load it later on. I found that one way is to use QVariant
. Here is a simplified Qt Widget Application example that I have created. But when I run it the binary file remains empty. Could you please help me with that. Also, Is there a better method to do such a thing?
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QFile>
#include <QFileDialog>
#include <QDataStream>
#include <QString>
#include "mystruct.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
/* create an object of the struct */
myStruct * aStruct = new myStruct;
aStruct->myStringVar = QString("aaaaa");
/* put the object in QVariant */
QVariant aVariant;
aVariant.setValue(aStruct);
/* save the QVariant to binary file */
QFile myFile("myFile");
QDataStream save(&myFile);
save.setVersion(QDataStream::Qt_4_6);
save << aVariant;
myFile.close();
/* load the QVariant from binary file */
QDataStream load(&myFile);
load.setVersion(QDataStream::Qt_4_6);
QVariant theVariant;
load >> theVariant;
QString theVar = theVariant.value<myStruct*>()->myStringVar;
myFile.close();
}
MainWindow::~MainWindow()
{
delete ui;
}
mystruct.h:
#ifndef MYSTRUCT_H
#define MYSTRUCT_H
#include <QMetaType>
#include <QString>
struct myStruct
{
QString myStringVar;
};
Q_DECLARE_METATYPE(myStruct*)
#endif // MYSTRUCT_H
Comment: As a reference, this link shows a similar problem, but I could not understand/implement the suggestions correctly. For example, I tried to define a new operator, as it is explained here, but it did not work.
First of all you should not save the pointer since this is only the memory address of the variable, what should be saved is the value. On the other hand if you want to use QDataStream you must overwrite stream operators, finally if you want to save as QVariant you must use qRegisterMetaTypeStreamOperators. In addition to the above, your code has several errors such as not opening the QFile.
mystruct.h
#ifndef MYSTRUCT_H
#define MYSTRUCT_H
#include <QString>
#include <QMetaType>
struct myStruct
{
QString myStringVar;
bool operator==(const myStruct & o){
return o.myStringVar == this->myStringVar;
}
friend QDataStream &operator<<(QDataStream &out, const myStruct &rhs){
out << rhs.myStringVar;
return out;
}
friend QDataStream &operator>>(QDataStream &in, myStruct &rhs){
in >> rhs.myStringVar;
return in;
}
};
Q_DECLARE_METATYPE(myStruct)
#endif // MYSTRUCT_H
main.cpp
#include "mystruct.h"
#include <QDataStream>
#include <QFile>
#include <QVariant>
int main(int argc, char *argv[])
{
qRegisterMetaTypeStreamOperators<myStruct>("myStruct");
// create struct
myStruct aStructIn{"aaa"};
// myStruct to QVariant
QVariant aVariant;
aVariant.setValue(aStructIn);
//open file
QFile myFile("myFile");
if(!myFile.open(QIODevice::WriteOnly))
return -1;
// save QVariant
QDataStream save(&myFile);
save.setVersion(QDataStream::Qt_4_6);
save << aVariant;
myFile.close();
//open file
if(!myFile.open(QIODevice::ReadOnly))
return -1;
// read QVariant
QDataStream load(&myFile);
load.setVersion(QDataStream::Qt_4_6);
QVariant theVariant;
load >> theVariant;
myFile.close();
// QVariant to myStruct
myStruct aStructOut = theVariant.value<myStruct>();
Q_ASSERT(aStructOut == aStructIn);
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With