c++ - 如何在 Qt 中使用 QDataStream 将自定义结构保存/加载到二进制文件中?
问题描述
我将在二进制文件中保存一个结构并稍后加载它。我发现一种方法是使用QVariant
. 这是我创建的一个简化的Qt Widget 应用程序示例。但是当我运行它时,二进制文件仍然是空的。你能帮我解决这个问题吗?另外,有没有更好的方法来做这样的事情?
主窗口.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
主窗口.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
评论:作为参考,此链接显示了类似的问题,但我无法正确理解/实施建议。例如,我试图定义一个新的运算符,正如这里所解释的那样,但它不起作用。
解决方案
首先你不应该保存指针,因为这只是变量的内存地址,应该保存的是值。另一方面,如果要使用 QDataStream,则必须覆盖流运算符,最后,如果要保存为 QVariant,则必须使用 qRegisterMetaTypeStreamOperators。除了上述之外,您的代码还有几个错误,例如没有打开 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
主文件
#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;
}
推荐阅读
- mysql - RDS 实例 CPU 为 99%
- watchkit - Apple Watch 上的 Scratchy AVAudioengine
- php - Laravel Collection groupBy() 不能使用 2 个值
- android - 应用程序未在发布模式下构建
- android - 来自属性的 BottomNavigationView 的自定义背景颜色
- swift - 在 UIImage 上添加 UIView - swift - 以编程方式
- java - 如何从java中的字符串中删除尖锐的重音?
- shopify - Shopify - 获取 Product Variant 的所有图像 - GraphQl
- json - 不能在 49 型和 31 型之间进行强制转换
- r - R:匹配两个数据框并在一个中创建新列