Qt最新事情-QtでWebKitを使ってみよう

第3回 Qtの基本プログラミング~オブジェクトモデル

この記事を読むのに必要な時間:およそ 6 分

はじめに

前回は,Qtの中核機能からシグナルとスロットというタイプセーフなコールバックについて説明しました。今回は,シグナルとスロットの実装の基礎となっているQtのオブジェクトモデルについて説明します。

オブジェクトモデル

Qtのオブジェクトモデルでは,C++オブジェクトにシグナルとスロットを含む表1の機能拡張をして,GUIプログラミングに必要とされる柔軟性を高めています。

表1 オブジェクトモデルで拡張された機能

シグナルとスロットタイプセーフコールバック,オブジェクトの疎結合とカプセル化
オブジェクトプロパティ問い合わせ可能なプロパティ
イベントとイベントフィルターイベント処理とイベントフック
国際化用テキスト文字列の翻訳クラスをコンテキストとするテキスト文字列翻訳
インターバルタイマーイベント処理と統合されたタイマー
オブジェクトツリーオブジェクトの階層化と検索
ガーディドポインターQPointer。Qt 4.5でQSharedPointerとQWeakPointerが追加
ダイナミックキャストライブラリ境界制限のないダイナミックキャスト

これらの機能は,オブジェクトクラスQObjectに対して実装されています。この中からオブジェクトプロパティ,オブジェクトツリー,ダイナミックキャストの3つ,それとこれらを支えているメタオブジェクトシステムについて説明します。

オブジェクトツリー

図1 コンポジットウィジェットの例

図1 コンポジットウィジェットの例

図1のように,既存のウィジェットをウィジェットの上に配置して作成するウィジェットをコンポジットウィジェットと呼び,以下の5つがその実装上のポイントです。

  1. ウィジエットがどのウィジェット上に置かれているか
  2. ウィジェットをどのように並べるか
  3. ウィジェットの表示/非表示の制御
  4. ウィジェットの有効化/無効化の制御
  5. ウィジェットのメモリ割り当てと解放の制御

Qtでは,これらの機能の実装にオブジェクトツリーが利用されています。2番目の「ウィジェットの並べ方」は,次回に詳しく説明します。

図1のコンポジットウィジェットのオブジェクトツリーは,レイアウトのためのオブジェクトを省略して,ウィジェットのみに着目すると,図2のようになります。

図2 図1のコンポジットウィジェットのオブジェクトツリー

図2 図1のコンポジットウィジェットのオブジェクトツリー

QFrameとQGroupBoxの親オブジェクトはQWidget,QLabelとQSliderの親オブジェクトはQGroupBoxです。QFrameの親クラスはQWidgetですが,QLabelやQSliderの親クラスはQGroupBoxでないことからわかるように,クラスの継承関係とは異なることに注意しましょう。これらのオブジェクトの親子関係はQObjectの機能で,QObjectを継承したQWidgetでは,この親子関係が,ウィジェットがどのウィジェットの上に乗っているかというウィジェットの上下関係に対応付けられています。

ウィジェットの親子関係に着目したコードはリスト1のようになります。

リスト1 ウィジェットの親子関係

class ColorChooser : public QWidget
{
...
private:
    QFrame* colorFrame;
    QSlider* redSlider;
    QSlider* greenSlider;
    QSlider* blueSlider;
}

ColorChooser::ColorChooser( QWidget* parent )
    : QWidget( parent )
{
    ...
    colorFrame = new QFrame(this);
    QGroupBox* colorGroupBox = new QGroupBox("RGB", this);

    QLabel* redLabel = new QLabel("&Red", groupBox);
    QLabel* greenLabel = new QLabel("&Green", groupBox);
    QLabel* blueLabel = new QLabel("&Blue", groupBox);
    redSlider = new QSlider(Qt::Horizontal, colorGroupBox);
    greenSlider = new QSlider(Qt::Horizontal, colorGroupBox);
    blueSlider = new QSlider(Qt::Horizontal, colorGroupBox);
    ...
}

ColorChooser::~ColorChooser()
{
    // 子ウィジェットのメモリ解放は不要。
}

ウィジェットのインスタンス生成時に親ウィジェットを指定しているのがポイントです。QObject またはその継承クラスのインスタンス生成では,親オブジェクトを指定して,オブジェクトツリーを形成できるようにしています。親オブジェクトは子オブジェクトのリストを持っていて,子オブジェクトは親オブジェクトを指すポインタを持っています。ウィジェットに親子関係を付けることによって,以下のことが可能となっています。

著者プロフィール

杉田研治(すぎたけんじ)

1955年生まれ。東京都出身。株式会社SRAに勤務。プログラマ。

仕事のほとんどをMac OS XとKubuntu KDE 4でQtと供に過ごす。

コメント

コメントの記入