nprogram’s blog

気ままに、プログラミングのトピックについて書いていきます

ユーザー定義クラス(独自クラス)のリストをQDataStreamにセーブ・ロードする方法 [Qt]

作成環境について

Qt Creator 4.3.1で、以下の設定で、プロジェクトを作成しております。以下の設定でクラス名、cppファイル名、hファイル名はすべてデフォルトを使用しています。

  • Qtウィジェットアプリケーション
  • 基底クラスは、QMainWindows
  • フォームを生成する

プログラムについて

メインウィンドウ終了時に、ユーザー定義クラスのリストをQDataStreamにセーブします。

再度、アプリケーションを実行したときに、前回終了時に保存したユーザー定義クラスのリストの情報を取り出すプログラムです。

変更ファイルは以下のとおり。

  • mainwindow.cpp
  • mainwindow.h

新規追加ファイルは以下のとおり。Paintクラスはユーザー定義クラス(独自クラス)となります。 * paint.cpp * paint.h

[mainwindow.cpp]

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QSettings>
#include <QSize>
#include <QDataStream>
#include <QFile>
#include <QDebug>
#include <iostream>

#include "paint.h"

const QString FILE_NAME = "out.txt";

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QFile file(FILE_NAME);
    file.open(QIODevice::ReadOnly);
    QDataStream in (&file);
    in.setVersion(QDataStream::Qt_5_9);

    // QDataStreamから、paintListの要素数を読み出す
    int paintListSize = 0;
    in >> paintListSize;

    // QDataStreamから、paintListの要素数分、ユーザー定義クラス(Paintクラス)の情報を読み出す
    for (int i = 0; i < paintListSize; i++) {
        Paint paint;
        in >> paint;
        std::cout << "title : " << paint._title.toStdString() << std::endl;
        std::cout << "age : " << paint._year << std::endl;
    }
}

MainWindow::~MainWindow()
{
    delete ui;
}

// Qtでは、closeEventをオーバーライドする事で実現可能です。
void MainWindow::closeEvent( QCloseEvent *event ){

    // ユーザー定義クラス(Paintクラス)をQLinkedListに追加する
    for (int i = 0; i < 5; i++) {
        Paint paint("Paint", i + 1900);
        QVariant vPaint = QVariant::fromValue(paint);
        paintList.append(vPaint);
    }

    QFile file(FILE_NAME);
    file.open(QIODevice::WriteOnly);
    QDataStream out (&file);
    out.setVersion(QDataStream::Qt_5_9);

    // QDataStreamに、paintListの要素数を格納する
    out << paintList.size();

    // QDataStreamに、ユーザー定義クラス(Paintクラス)を格納する
    foreach (QVariant item, paintList) {
        Paint paint =  item.value<Paint>();
        out << paint;
    }
}

[mainwindow.h]

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLinkedList>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

protected:
    virtual void closeEvent( QCloseEvent *event );
    QLinkedList<QVariant> paintList;

};

#endif // MAINWINDOW_H

[paint.cpp]

#include "paint.h"

QDataStream &operator << (QDataStream &out, const Paint &paint)
{
    out << paint._title << qint32(paint._year);
    return out;
}

QDataStream &operator >> (QDataStream &in, Paint &paint)
{
    QString title;
    qint32 year;

    in >> title >> year;

    paint = Paint(title, static_cast<int>(year));

    return in;
}

[paint.h]

#ifndef PAINT_H
#define PAINT_H

#include <QString>
#include <QDataStream>

class Paint
{
public:
    QString _title;
    int _year;

public:
    Paint(){}
    Paint(QString title, int year) {
        _title = title;
        _year = year;
    }
};

// Q_DECLARE_METATYPEマクロにより、QMetaTypeに独自の型を登録
Q_DECLARE_METATYPE(Paint)

QDataStream &operator << (QDataStream &out, const Paint &paint);
QDataStream &operator >> (QDataStream &in, Paint &paint);

#endif // PAINT_H

実行結果

以下のように、前回終了時に保存したユーザー定義クラスのリストの情報を取り出すができました。

f:id:nprogram:20170808063925p:plain