LoginSignup
3
2

More than 5 years have passed since last update.

QtのUiクラスをPimplイディオムで隠蔽する

Posted at

Qtの自動生成クラス(Visual Studio Add-in)

QtのVisual Studio Add-inで開発する場合、UIのクラスを作成すると次のようなコードが生成されます。

foowidget.h
#ifndef FOOWIDGET_H
#define FOOWIDGET_H

#include <QWidget>
#include "ui_foowidget.h"

class FooWidget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::FooWidget ui;
};

#endif // FOOWIDGET_H
foowidget.c
#include "foowidget.h"

FooWidget::FooWidget(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
}

FooWidget::~FooWidget()
{
}

ここではUiクラスのヘッダ(ui_foowidget.h)がWidgetクラスのヘッダ(foowidget.h)に含まれます。
すると、Uiクラスを更新した際にWidgetクラスのヘッダを読み込んでいるすべてのファイルで再コンパイルが必要になります。
コンパイル時間が長くなるため、開発のリズムが悪くなってしまいます。

PimplクラスによるUiクラスの隠蔽

Pimplイディオムを使ってUiクラスを隠蔽します。
ヘッダからUiクラスの痕跡を消すことができるので基本的にこの方法で記載します。
他のクラスからFooWidgetのUiへ直接アクセスできなくなるので注意が必要です。

foowidget.h
#ifndef FOOWIDGET_H
#define FOOWIDGET_H

#include <memory>
#include <QWidget>

class FooWidget : public QWidget
{
    Q_OBJECT

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

private:
    struct Impl;
    std::unique_ptr<Impl> pImpl;

    // Ui::FooWidget ui;  Uiクラスはcppファイルで宣言する
};

#endif // FOOWIDGET_H
foowidget.cpp
#include "foowidget.h"
#include "ui_foowidget.h"

struct FooWidget::Impl
{
    Ui::FooWidget ui;

    Impl(FooWidget*const obj)
    {
        ui.setupUi(obj); // FooWidgetのthisオブジェクトをImplクラスに渡す
    }
};

FooWidget::FooWidget(QWidget *parent)
    : QWidget(parent)
    , pImpl(new FooWidget::Impl(this))
{
}

FooWidget::~FooWidget()
{
}

Qtの自動生成クラス(Qt Creater)

Qt Createrでは、以下のように自動生成されます。
cppファイルにUiクラスのヘッダが記載されています。

foowidget.h
#ifndef FOOWIDGET_H
#define FOOWIDGET_H

#include <QWidget>

namespace Ui {
class FooWidget;
}

class FooWidget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::FooWidget *ui;
};

#endif // FOOWIDGET_H
foowidget.cpp
#include "foowidget.h"
#include "ui_foowidget.h"

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

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

環境

VC2013
Qt 5.4
Qt Visual Studio Add-in 1.2.5
Qt Creater 4.0.2

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2