C++
Qt

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

More than 1 year has passed since last update.


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