Qt をはじめよう! 第8回: QWidget の親子関係を学ぼう

Posted by 鈴木 佑 on 2010/05/21

前回QObject の親子関係について学びました。今回は QWidget についてです。

QWidget

QWidgetQObject のサブクラスで、Qt の全てのウィジェットの基底クラスです。

ウィジェットとは GUI を構成する各要素のことをいいます。ラベルやボタン、ウィンドウそのもの等です。

QWidget は以下のようなウィジェットとしての基本的な機能を提供します。

QWidget の親子関係

それぞれの QWidget は親ウィジェットを持つことができ、以下の API より設定できます。

QWidget は QObject を継承しているため、QObject の親子関係がそのまま成り立ちます。QWidget ではそれに加えて以下のウィジェットとしての親子関係が成立します。

  • 子ウィジェットの位置は親ウィジェットに対する相対的な位置になる
  • 子ウィジェットは、親ウィジェットの範囲内に描画される
  • 子ウィジェットでは(明示的な指定がない場合) visible, enabled, palette, font 等のプロパティは親ウィジェットから引き継がれ、親ウィジェットのこれらのプロパティが変更された場合には子ウィジェットにも伝搬する

また、親ウィジェットを持たないウィジェットは ウィンドウ となり、最小化/最大化等ののボタンを含むタイトルバーやウィンドウの枠が表示され、各プラットフォームのウィンドウマネージャーによって管理されます。
それでは以下のアプリケーションのプログラムを書きながら実際の動きを確認してみましょう。

新しいプロジェクトの作成

ファイル(F) -> ファイル/プロジェクトの新規作成(N)… を選択してください。
今回も「Qt4 GUI アプリケーション」を選択します。

プロジェクト名とパス

example という名前のアプリケーションを作成します。

必須モジュールの選択

今回は QtCore と QtGui モジュールのみを使用します。そのまま次へをクリックしてください。

クラス情報

クラス名:Example と入力

基底クラス:QWidget を選択

フォームを生成する:チェックを外す

として、次へをクリックしてください。

今回は UI をソースコードで生成するため、フォームは使用しません。

プロジェクト管理


完了をクリックするとアプリケーションのテンプレートが生成されます。

子ウィジェットの生成とジオメトリ(位置、大きさ)の設定

QSliderQPushButton を上下に並べて配置します。

example.cpp を開き以下のように編集してください。

#include "example.h"
#include <QSlider>     // [1]
#include <QPushButton> // [2]

Example::Example(QWidget *parent)
    : QWidget(parent)
{
    QSlider *slider = new QSlider(Qt::Horizontal, this);  // [3]
    slider->setGeometry(10, 10, 200, 20);                 // [4]
    QPushButton *button = new QPushButton("Close", this); // [5]
    button->setGeometry(10, 40, 200, 30);                 // [6]
}

[1] [3] で使用するQSliderのヘッダファイルをインクルード

[2] [5] で使用するQPushButtonのヘッダファイルをインクルード

[3] 親ウィジェットに this(Example) を指定し水平方向の QSlider のインスタンス slider を生成

[4] slider のジオメトリの設定

[5] 親ウィジェットに this(Example) を指定し ”Close” というテキストの QPushButton のインスタンス button を生成

[6] button のジオメトリの設定


それでは実行してみましょう。

Example クラスのコンストラクタで生成した2つのウィジェットが Example の子ウィジェットとして表示されています。スライダを動かしたりボタンを押したりすることは可能ですが、動作は実装していないため何も起こりません。

Example::~Example()
{

}

Example クラスのデストラクタでは何もしていない点に着目してください。

Example を親オブジェクトとして指定して生成した slider, button は、Example のインスタンスが delete される際に自動で delete されるためここで delete をする必要はありません。(delete しても問題はありません。)

main.cpp

main.cpp を開き、ソースコードを見てみましょう。

下記の内容は典型的な Qt のアプリケーションにおける main.cpp のコードになります。

#include <QtGui/QApplication> // [1]
#include "example.h"          // [2]

int main(int argc, char *argv[])
{
    QApplication a(argc, argv); // [3]
    Example w;                  // [4]
    w.show();                   // [5]
    return a.exec();            // [6]
}

[1] [3] で使用する QApplication のヘッダファイルをインクルード

[2] [4] で使用する Example のヘッダファイルをインクルード

[3] QApplication のインスタンス a を生成

[4] Example のインスタンス w を生成

[5] w を表示

[6] a を実行し、Qt のイベントループに入る

[4] で Example のインスタンス w を生成した際に親ウィジェットを指定していないことに着目してください。w は親ウィジェットを持たないウィジェットとなり、ウインドウとして扱われます。

おわりに

今回は QWidget の親子関係について学びました。

プログラミングでは QWidget のサブクラスを作成し、その中で子ウィジェットを生成して表示しました。

今回は子ウィジェットの位置や大きさを固定値で指定したため、ウィンドウのサイズを変更した場合には見た目がおかしくなってしまいます。

次回はこの問題を解決するレイアウトという仕組みについて学びましょう。

Did you like this? Share it:

Related posts:

  1. Qt をはじめよう! 第9回: レイアウト管理を学ぼう
  2. Qt をはじめよう! 第7回: Qt のオブジェクトモデルを理解しよう
  3. Qt をはじめよう! 第10回: シグナルとスロット
  4. Qt をはじめよう! 第12回: シグナルとスロットを作成しよう
  5. Qt をはじめよう! 第11回: QObject の派生クラスを作成しよう

1 comment  (read them below or add one)

nakasya 2010/09/08 12:13
 

QObjectも含め親子関係の説明がくることにとても好感がもてました。
しかし、このページのプロジェクト名が曖昧なものになってしまい残念です。繰り返し見直す際にExampleだけではもったいないと思いました。

コメントする

前の投稿へ:

次の投稿へ: