はじめに
前回は、
レイアウトマネージメントとは
表1のように、
種類 | 説明 |
---|---|
コンポジットウィジェット | ウィジェットを配置して作成するウィジェット |
グラフィカルウィジェット | アナログ時計やVUメーターのようなウィジェット |
グラフィカルウィジェットは、
方法 | 説明 |
---|---|
位置とサイズ指定 | ウィジェットの絶対位置とサイズを指定して並べる機能。どのGUIツールキットも必ず持っているウィジェット配置機能。 |
レイアウトマネージメント | ウィジェットの相対関係を指定してウィジェットを並べたり、 |
位置とサイズは、
- 日本語や英語などの言語の変更
- ウィンドウサイズの変更
- フォントの種類やフォントサイズの変更
そこで、
Qtのレイアウトポリシー
Qtでは、
レイアウトクラス | 説明 |
---|---|
QBoxLayout | 縦(上から下、 |
QHBoxLayout | QBoxLayoutを継承し、 |
QVBoxLayout | QBoxLayoutを継承し、 |
QGridLayout | 格子状に並べる。 |
QFormLayout | n行2列に並べる。ラベル付きで入力ウィジェットを並べることに特化。Qt 4. |
QStackedLayout | 前後に重ね合わせて、 |
いろいろありますが、
レイアウトマネージャは、
レイアウトの作成方法
ベースのウィジェット上にウィジェットを配置するには、
QVBoxLayout* topLayout = new QVBoxLayout(this);
QLabel* messageLabel = new QLabel(this);
topLayout->addWidget(messageLabel);
QPushButton* okButton = new QPushButton("Ok", this);
QPushButton* cancelButton = new QPushButton("Cancel", this);
QHBoxLayout* buttonLayout = new QHBoxLayout;
buttonLayout->addWidget(okButton);
buttonLayout->addWidget(cancelButton);
topLayout->addLayout(buttonLayout);
リスト2は、
QLabel* messageLabel = new QLabel(this);
QPushButton* okButton = new QPushButton("Ok");
QPushButton* cancelButton = new QPushButton("Cancel");
QHBoxLayout* buttonLayout = new QHBoxLayout;
buttonLayout->addWidget(okButton);
buttonLayout->addWidget(cancelButton);
QVBoxLayout* topLayout = new QVBoxLayout;
topLayout->addWidget(messageLabel);
topLayout->addLayout(buttonLayout);
setLayout(topLayout);
レイアウト内に配置されるオブジェクト
インスタンス生成に時間がかかったり再生成が困難なウィジェットがある場合には、
レイアウト内には、
- ウィジェット
ラベルやボタンなどのウィジェット。addWidget()でレイアウトに入れる。 - レイアウト
レイアウト自体も並べられる、つまりネストしたレイアウト。addLayout()でレイアウトに入れる。 - スペーサー
QSpacerItemのインスタンス。縦横の広がりを持つ空白で表示はされない。固定サイズのスペーサーはaddSpacing()、伸縮するスペーサーはaddStretch()でレイアウトに入れる。
リスト3は固定サイズのボタンと伸縮するスペースに合わせて伸縮するボタンを並べたレイアウト記述で、
QPushButton* button11 = new QPushButton("Button 11");
QPushButton* button12 = new QPushButton("Button 12");
QPushButton* button13 = new QPushButton("Button 13");
QPushButton* button14 = new QPushButton("Button 14");
QHBoxLayout* buttonLayout1 = new QHBoxLayout;
buttonLayout1->addWidget(button11);
buttonLayout1->addSpacing(12); // 固定サイズのスペース
buttonLayout1->addWidget(button12);
buttonLayout1->addWidget(button13);
buttonLayout1->addStretch(); // 伸縮するスペース
buttonLayout1->addWidget(button14);
QPushButton* button21 = new QPushButton("Button 21");
QPushButton* button22 = new QPushButton("Button 21");
QHBoxLayout* buttonLayout2 = new QHBoxLayout;
buttonLayout2->addWidget(button21);
buttonLayout2->addWidget(button22);
QVBoxLayout* topLayout = new QVBoxLayout;
topLayout->addLayout(buttonLayout1);
topLayout->addLayout(buttonLayout2);
QWidget top;
top.setLayout(topLayout);

オブジェクトツリーは図2のようになり、


レイアウト内にどのようにオブジェクトが存在しているかを把握するのは、
いろいろなスペースとサイズ制約
いろいろなスペースの取り方やウィジェットのサイズ制約方法によって、
いろいろなスペース
スペースには、
種類 | 説明 |
---|---|
マージン | レイアウトに並べたウィジェットの上下左右に取られるスペース。QLayout::getContentsMargins()/ |
スペーシング | レイアウトに並べるウィジェットの間隔。レイアウトオブジェクトのspacingプロパティで、 |
可変スペース | レイアウトに配置された可変サイズのQSpacerItemオブジェクト。 |
固定スペース | レイアウトに配置された固定サイズのQSpacerItemオブジェクト。 |
サイズヒントとサイズポリシー
サイズヒントは、
グラフィカルなウィジェットには、
コンポジットウィジェットは、
サイズポリシーは、
種類 | 説明 |
---|---|
QSizePolicy::Fixed | サイズヒントに常に固定。 |
QSizePolicy::Minimum | サイズヒントが最小サイズで、 |
QSizePolicy::Maximum | サイズヒントが最大サイズで、 |
QSizePolicy::Preferred | サイズヒントが最適サイズで、 |
QSizePolicy::Expanding | 伸縮できるが拡大の方が適している。 |
スペーサーにもサイズヒントとサイズポリシーがあり、
サイズ制約
QWidgetのminimumSizeとmaximumSizeのプロパティが最小サイズと最大サイズで、
ストレッチ
サイズポリシーには、
ストラット
レイアウトストラットとグローバルストラットの2種類のストラットがあります。レイアウトストラットはaddStrut(int)でで設定し、
グローバルストラットは、
heightForWidth()
ウィジェットやレイアウトの幅に対応して高さが定まるような場合に使われます。たとえば、
レイアウトマネージメントの補足事項
- 必ずしもすべてのウィジェットをレイアウトマネージメント機能の配下に置く必要はありません。インジケータのようなウィジェットを浮かせて、
他のウィジェットの上に部分的に重ねることもあります。そのようなウィジェットは、 レイアウトには入れずに使います。 - Qt Designerのようにグラフィカルにウィジェットを編集するツールは、
レイアウトコードを使いこなせるようになってから使ってこそ効果的です。レイアウトがどのようなことをしているかを本質的に掴めるようになるには、 コードで記述できることが必須です。GUI操作では使えるレイアウト機能が部分的であったり、 GUI操作のために便宜的な操作方法を取っていたりしているため、 本質的なことを掴みにくいからです。 - レイアウト機能で並べているウィジェットに、
位置やサイズの直接指定はできません。たとえば、 横に並んでいるウィジェットの片方の端のウィジェットをmove()で呼び出して、 もう一方の端に位置を変えようとすれば、 レイアウトマネージャが並べようとしていることと矛盾してしまいます。 - 矛盾するレイアウト要求もあります。レイアウトマネージャが常に全ウィジェットの要求を満たせるとは限りません。たとえば、
80×200の固定サイズのベースウィジェット上に、 60×50の固定サイズの子ウィジェットを縦に5つは並べられません。子ウィジェットの高さは50よりも小さくなった状態で並べられるでしょう。
まとめと次回の予告
Qtのアーキテクチャの中から、