QT 自定义结构体的内容存储在dat文件中

使用的是QDataStream进行文件数据流的存储

QT自带的QDataStream只能传递它自己要求的数据类型。但是我们可以自己重载QDataStream& operator<<()和QDataStream& operator>>();这样我们就可以传递struct的类型了

串行化(Serialization)是计算机科学中的一个概念,它是指将对象存储到介质(如文件、内存缓冲区等)中或是以二进制方式通过网络传输。之后可以通过反串行化从这些连续的字节(byte)数据重新构建一个与原始对象状态相同的对象,因此在特定情况下也可以说是得到一个副本,但并不是所有情况都这样。
Qt 对这类组合数据的打包方法就叫串行化(Serializing),在 Qt 帮助文档的索引里输入关键词 Serializing 就可以看到关于 Qt 串行化的帮助主题(Serializing Qt Data Types),除了 C++ 基本数值类型,Qt 还对大量自身的类对象做了串行化。串行化得到一个字节数组 QByteArray ,可以直接用于发送。Qt 串行化数据接收就是发送的逆过程,都是通过 QDataStream 流实现。

1、首先新建一个类,存储三个不同类型的字段信息;

class T
{
public:
    int a;
    double b;
    QString c;
    T(int a1, double b1, QString c1);
    friend QDataStream& operator<<(QDataStream &out, const T &t);
    friend QDataStream& operator>>(QDataStream &in, T &t);
};
T::T(int a1, double b1, QString c1)
{
    a = a1;
    b = b1;
    c = c1;
}

2、分别重写文件读写操作


QDataStream& operator <<(QDataStream &out, const T &t)
{
    out << t.a << t.b << t.c;
    return out;
}
QDataStream& operator >>(QDataStream &in, T &t)
{
    int a;
    double b;
    QString c;
    in >> a >> b >> c;
    t.a = a;
    t.b = b;
    t.c = c;
    return in;
}

3、分别在main函数进行相对应的文件操作即可

    //文件写入
    T t(1, 2, "3");
    QFile writeFile("test.dat");
    writeFile.open(QIODevice::WriteOnly);
    QDataStream out(&writeFile);
    out << t;
    writeFile.close();
    //文件读取
    QFile readFile("test.dat");
    readFile.open(QIODevice::ReadOnly);
    QDataStream in(&readFile);
    in >> t;
    readFile.close();
    qDebug() << t.a << t.b << t.c;

注意最开始的引用:

#include <QApplication>
#include <QtCore/QCoreApplication>
#include <QFile>
#include <QByteArray>
#include <QDebug>

字符串写入 串行化的示例

#include <QCoreApplication>

//qtcodec.cpp
#include <QDebug>
#include <iostream>
#include <QByteArray>
#include <QDataStream>

using namespace std;
QByteArray TestSerialOut()
{
    //数据
    int nVersion = 1;
    double dblValue = 125.78999;
    QString strName = QObject::tr("This an example.");
    //字节数组保存结果
    QByteArray baResult;
    //串行化的流
    QDataStream dsOut(&baResult, QIODevice::ReadWrite);  //做输出,构造函数用指针
    //设置Qt串行化版本
    dsOut.setVersion(QDataStream::Qt_5_0);//使用Qt 5.0 版本流
    //串行化输出
    dsOut<<nVersion<<dblValue<<strName;

//    //显示长度
//    qDebug()<<baResult.length()<<"\t"<<qstrlen(baResult.data());
    //返回对象
    return baResult;
}

void TestSerialIn(const QByteArray& baIn)
{
    //输入流
    QDataStream dsIn(baIn); //只读的流,构造函数用常量引用
    //设置Qt串行化版本
    dsIn.setVersion(QDataStream::Qt_5_0);//使用Qt 5.0 版本流
    //变量
    int nVersion;
    double dblValue;
    QString strName;
    //串行化输入
    dsIn>>nVersion>>dblValue>>strName;

    //打印
    qDebug()<<nVersion;
    qDebug()<<fixed<<dblValue;
    qDebug()<<strName;
}



int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QByteArray ba = TestSerialOut();
    TestSerialIn(ba);

    return a.exec();
}

  • 3
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt,可以通过继承自QWidget或QAbstractItemDelegate,实现自定义结构体控件。 以下是一些基本的步骤: 1. 定义一个结构体用于存储需要显示的数据。 ```c++ struct MyStruct { QString name; int age; }; ``` 2. 创建一个继承自QWidget或QAbstractItemDelegate的类,并将结构体作为其员变量。 ```c++ class MyStructWidget : public QWidget { Q_OBJECT public: MyStructWidget(QWidget *parent = nullptr); ~MyStructWidget(); void setData(const MyStruct &data); MyStruct getData() const; private: QLabel *nameLabel; QLabel *ageLabel; MyStruct m_data; }; ``` 或者: ```c++ class MyStructDelegate : public QAbstractItemDelegate { public: MyStructDelegate(QObject *parent = nullptr); QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; void setEditorData(QWidget *editor, const QModelIndex &index) const override; void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override; void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; }; ``` 3. 在自定义控件类的构造函数,创建控件并设置布局。 ```c++ MyStructWidget::MyStructWidget(QWidget *parent) : QWidget(parent) { nameLabel = new QLabel(this); ageLabel = new QLabel(this); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(nameLabel); layout->addWidget(ageLabel); setLayout(layout); } ``` 4. 实现setData和getData函数,用于设置和获取数据。 ```c++ void MyStructWidget::setData(const MyStruct &data) { m_data = data; nameLabel->setText(data.name); ageLabel->setText(QString::number(data.age)); } MyStruct MyStructWidget::getData() const { return m_data; } ``` 或者: ```c++ QWidget *MyStructDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { MyStructWidget *editor = new MyStructWidget(parent); return editor; } void MyStructDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { MyStruct data = index.model()->data(index, Qt::EditRole).value<MyStruct>(); static_cast<MyStructWidget*>(editor)->setData(data); } void MyStructDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { MyStruct data = static_cast<MyStructWidget*>(editor)->getData(); model->setData(index, QVariant::fromValue(data), Qt::EditRole); } void MyStructDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const { editor->setGeometry(option.rect); } void MyStructDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { MyStruct data = index.model()->data(index, Qt::DisplayRole).value<MyStruct>(); QString text = data.name + " " + QString::number(data.age); painter->drawText(option.rect, text); } ``` 5. 在使用自定义控件的地方,设置模型数据或委托。 ```c++ // 使用QWidget控件 MyStructWidget *widget = new MyStructWidget(this); MyStruct data = { "Tom", 18 }; widget->setData(data); // 使用QAbstractItemDelegate QStandardItemModel *model = new QStandardItemModel(this); model->setItemDelegate(new MyStructDelegate(this)); model->setItem(0, new QStandardItem("Tom 18")); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值