本文へスキップします。

本文へ

【全Qt】
【全・Qt】SRAロゴ
H1

技術記事:はじめての Qt Creator (その 4) - フォーム編集 - 生成コード

技術記事

(掲載 2023年9月26日)

デバッグ

前回のフォーム編集の基礎知識の説明について、実際に動かして練習をします。


.ui ファイルから生成されるコード

水平/垂直ボックスレイアウト

前回のフォーム編集の 水平/垂直ボックスレイアウト で、サイズ調整後のフォーム編集状態は、以下のようになっていました。



前回示した .ui ファイルから生成されたコードには、レイアウト以外のコードがあって手書きコードよりも長いコードです。レイアウトに関係する部分を抜き出すと以下のようになります。

Widget->resize(280, 260);

verticalLayout = new QVBoxLayout(Widget);

textEdit = new QTextEdit(Widget);
verticalLayout->addWidget(textEdit);

buttonLayout = new QHBoxLayout();

leftButton = new QPushButton(Widget);
buttonLayout->addWidget(leftButton);

rightButton = new QPushButton(Widget);
buttonLayout->addWidget(rightButton);

verticalLayout->addLayout(buttonLayout);

このコードは、手書きでも全く同じです。さらにフォーム編集をすると、どのように生成コードが変わるかを見ていきましょう。

2 つの Push Button を囲むレイアウトのスペーシングを 0 にすると、フォーム編集状態は以下のようになります。



生成コードは、以下のようになります。太字の部分が追加されました。手書きでもこのようになります。

Widget->resize(280, 260);

verticalLayout = new QVBoxLayout(Widget);

textEdit = new QTextEdit(Widget);
verticalLayout->addWidget(textEdit);

buttonLayout = new QHBoxLayout();
buttonLayout->setSpacing(0);

leftButton = new QPushButton(Widget);
buttonLayout->addWidget(leftButton);

rightButton = new QPushButton(Widget);
buttonLayout->addWidget(rightButton);

verticalLayout->addLayout(buttonLayout);

左の Push Button 横方向のストレッチを 1 に設定すると、フォーム編集状態は以下のようになります。

生成コードは、以下のようになります。太字の部分が元のコードに対して、追加されたコードです。

Widget->resize(280, 260);

verticalLayout = new QVBoxLayout(Widget);

textEdit = new QTextEdit(Widget);
verticalLayout->addWidget(textEdit);

buttonLayout = new QHBoxLayout();
buttonLayout->setSpacing(0);

leftButton = new QPushButton(Widget);
QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
sizePolicy.setHorizontalStretch(1);
sizePolicy.setVerticalStretch(0);
sizePolicy.setHeightForWidth(leftButton->sizePolicy().hasHeightForWidth());
leftButton->setSizePolicy(sizePolicy);
buttonLayout->addWidget(leftButton);

rightButton = new QPushButton(Widget);
buttonLayout->addWidget(rightButton);

verticalLayout->addLayout(buttonLayout);

これは手書きのコードとは違います。手書きの場合には、以下のように addWidget() の第 2 実引数で、ストレッチファクターを指定し、レイアウトのストレッチファクターとして使われるようにします。

Widget->resize(280, 260);

verticalLayout = new QVBoxLayout(Widget);

textEdit = new QTextEdit(Widget);
verticalLayout->addWidget(textEdit);

buttonLayout = new QHBoxLayout();
buttonLayout->setSpacing(0);

leftButton = new QPushButton(Widget);
buttonLayout->addWidget(leftButton, 1);

rightButton = new QPushButton(Widget);
buttonLayout->addWidget(rightButton);

verticalLayout->addLayout(buttonLayout);

右の Push Button の横方向のストレッチを 2 に設定すると、フォーム編集状態は以下のようになります。

生成コードは。以下のようになります。

Widget->resize(280, 260);

verticalLayout = new QVBoxLayout(Widget);

textEdit = new QTextEdit(Widget);
verticalLayout->addWidget(textEdit);

buttonLayout = new QHBoxLayout();
buttonLayout->setSpacing(0);

leftButton = new QPushButton(Widget);
QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
sizePolicy.setHorizontalStretch(1);
sizePolicy.setVerticalStretch(0);
sizePolicy.setHeightForWidth(leftButton->sizePolicy().hasHeightForWidth());
leftButton->setSizePolicy(sizePolicy);

buttonLayout->addWidget(leftButton);

rightButton = new QPushButton(Widget);
QSizePolicy sizePolicy1(QSizePolicy::Minimum, QSizePolicy::Fixed);
sizePolicy1.setHorizontalStretch(2);
sizePolicy1.setVerticalStretch(0);
sizePolicy1.setHeightForWidth(rightButton->sizePolicy().hasHeightForWidth());
rightButton->setSizePolicy(sizePolicy1);
buttonLayout->addWidget(rightButton);

verticalLayout->addLayout(buttonLayout);

手書きの場合は、以下のように addWidget(rightButton, 2) を呼び出します。

Widget->resize(280, 260);

verticalLayout = new QVBoxLayout(Widget);

textEdit = new QTextEdit(Widget);
verticalLayout->addWidget(textEdit);

buttonLayout = new QHBoxLayout();
buttonLayout->setSpacing(0);

leftButton = new QPushButton(Widget);
buttonLayout->addWidget(leftButton, 1);

rightButton = new QPushButton(Widget);
buttonLayout->addWidget(rightButton, 2);

verticalLayout->addLayout(buttonLayout);

2 つの Push Button の間に Horizontal Spacer をドラグ&ドロップして配置します。

生成コードは。以下のようになります。

Widget->resize(280, 260);

verticalLayout = new QVBoxLayout(Widget);

textEdit = new QTextEdit(Widget);
verticalLayout->addWidget(textEdit);

buttonLayout = new QHBoxLayout();
buttonLayout->setSpacing(0);

leftButton = new QPushButton(Widget);
QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
sizePolicy.setHorizontalStretch(1);
sizePolicy.setVerticalStretch(0);
sizePolicy.setHeightForWidth(leftButton->sizePolicy().hasHeightForWidth());
leftButton->setSizePolicy(sizePolicy);

buttonLayout->addWidget(leftButton);
horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
buttonLayout->addItem(horizontalSpacer);

rightButton = new QPushButton(Widget);
QSizePolicy sizePolicy1(QSizePolicy::Minimum, QSizePolicy::Fixed);
sizePolicy1.setHorizontalStretch(2);
sizePolicy1.setVerticalStretch(0);
sizePolicy1.setHeightForWidth(rightButton->sizePolicy().hasHeightForWidth());
rightButton->setSizePolicy(sizePolicy1);
buttonLayout->addWidget(rightButton);

verticalLayout->addLayout(buttonLayout);

可変長の QSpacerItem のインスタンスを addItem() でレイアウトに追加しています。

手書きの場合は、以下のように addStretch() を呼び出して、レイアウトに可変長の QSpacerIItem インスタンスを追加します。

Widget->resize(280, 260);

verticalLayout = new QVBoxLayout(Widget);

textEdit = new QTextEdit(Widget);
verticalLayout->addWidget(textEdit);

buttonLayout = new QHBoxLayout();
buttonLayout->setSpacing(0);

leftButton = new QPushButton(Widget);
buttonLayout->addWidget(leftButton, 1);

buttonLayout->addStretch();

rightButton = new QPushButton(Widget);
buttonLayout->addWidget(rightButton, 2);

verticalLayout->addLayout(buttonLayout);

スペーサーをクリックして選択し、sizeType プロパティーを Fixed に変更します。

生成コードは。以下のようになります。

Widget->resize(280, 260);

verticalLayout = new QVBoxLayout(Widget);

textEdit = new QTextEdit(Widget);
verticalLayout->addWidget(textEdit);

buttonLayout = new QHBoxLayout();
buttonLayout->setSpacing(0);

leftButton = new QPushButton(Widget);
QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
sizePolicy.setHorizontalStretch(1);
sizePolicy.setVerticalStretch(0);
sizePolicy.setHeightForWidth(leftButton->sizePolicy().hasHeightForWidth());
leftButton->setSizePolicy(sizePolicy);

buttonLayout->addWidget(leftButton);
horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Fixed, QSizePolicy::Minimum);
buttonLayout->addItem(horizontalSpacer);

rightButton = new QPushButton(Widget);
QSizePolicy sizePolicy1(QSizePolicy::Minimum, QSizePolicy::Fixed);
sizePolicy1.setHorizontalStretch(2);
sizePolicy1.setVerticalStretch(0);
sizePolicy1.setHeightForWidth(rightButton->sizePolicy().hasHeightForWidth());
rightButton->setSizePolicy(sizePolicy1);
buttonLayout->addWidget(rightButton);

verticalLayout->addLayout(buttonLayout);

QSpacerItem の横方向のサイズポリシーが QSizePolicy::Fixed に変わっています。

手書きの場合は、以下のように addSpacing() を呼び出して、レイアウトに固定長の QSpacerIItem インスタンスを追加します。

Widget->resize(280, 260);

verticalLayout = new QVBoxLayout(Widget);

textEdit = new QTextEdit(Widget);
verticalLayout->addWidget(textEdit);

buttonLayout = new QHBoxLayout();
buttonLayout->setSpacing(0);

leftButton = new QPushButton(Widget);
buttonLayout->addWidget(leftButton, 1);

buttonLayout->addSpacing(40);

rightButton = new QPushButton(Widget);
buttonLayout->addWidget(rightButton, 2);

verticalLayout->addLayout(buttonLayout);

2 つの Push Button のストレッチファクターをデフォルトの 0 に戻し、スペーサーの sizeType もデフォルトの Expanding に戻します。

Widget->resize(280, 260);

verticalLayout = new QVBoxLayout(Widget);

textEdit = new QTextEdit(Widget);
verticalLayout->addWidget(textEdit);

buttonLayout = new QHBoxLayout();
buttonLayout->setSpacing(0);

leftButton = new QPushButton(Widget);
QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
sizePolicy.setHeightForWidth(leftButton->sizePolicy().hasHeightForWidth());
leftButton->setSizePolicy(sizePolicy);

buttonLayout->addWidget(leftButton);
horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
buttonLayout->addItem(horizontalSpacer);

rightButton = new QPushButton(Widget);
sizePolicy.setHeightForWidth(rightButton->sizePolicy().hasHeightForWidth());
rightButton->setSizePolicy(sizePolicy);
buttonLayout->addWidget(rightButton);

verticalLayout->addLayout(buttonLayout);

手書きの場合は、以下のようになります。

Widget->resize(280, 260);

verticalLayout = new QVBoxLayout(Widget);

textEdit = new QTextEdit(Widget);
verticalLayout->addWidget(textEdit);

buttonLayout = new QHBoxLayout();
buttonLayout->setSpacing(0);

leftButton = new QPushButton(Widget);
buttonLayout->addWidget(leftButton);

buttonLayout->addStretch();

rightButton = new QPushButton(Widget);
buttonLayout->addWidget(rightButton);

verticalLayout->addLayout(buttonLayout);

次は、.ui ファイルから生成されたコードで、アライメントがどのようになるか見ていきましょう。

Push Button を垂直ボックスレイアウトに入れると、以下のようになります。

生成されたコードからレイアウトに関係する部分を抜き出すと以下のようになります。

Widget->resize(400, 300);
topLayout = new QVBoxLayout(Widget);

button = new QPushButton(Widget);

topLayout->addWidget(button);

このコードは、手書きでも全く同じです。

  • 中央揃え(横方向) にします。
  • 生成されたコードは、以下のようになります。

    Widget->resize(400, 300);
    topLayout = new QVBoxLayout(Widget);
    
    button = new QPushButton(Widget);
    
    topLayout->addWidget(button, 0, Qt::AlignHCenter);
    

    addWidget() をストレッチファクターを 0 (デフォルト)、アラインメントを Qt::AlignHCenter で呼び出しています。

    手書きの場合にも、同じようにします。また、以下のようにもして、アラインメントを設定できます。

    topLayout->setAlignment(button, Qt::AlignHCenter);
    

    左端揃えや他の揃え方もアラインメントの値が違うだけです。

    .ui から生成されるコードは、手書きのコードよりも複雑になる場合がありますが、本質的結果は、どちらも同じです。

    次回は、第 1 回で挙げたカスタムウィジェットのフォーム編集を実際に試す予定です。

    はじめての Qt Creator:連載案内

    この連載は掲載当時の画面と操作に基づいています。Qt CreatorのバージョンやOSによって、メニュー名・設定項目・生成コードが異なる場合があります。

    1. 第1回:ウィジェットアプリケーション
    2. 第2回:フォーム編集 - 基礎知識
    3. 第3回:フォーム編集 - 練習
    4. 第4回:フォーム編集 - 生成コード
    5. 第5回:フォーム編集 - カスタムウィジェット
    6. 第6回:部品化 - カスタムウィジェット

    フォームと C++ コードの設計を相談するときに用意するとよい情報

    フォームから生成されるコードの理解や、手書きの C++ コードとの役割分担、コードレビューについては、SRA にご相談ください。使用中の Qt・Qt Creator のバージョン、画面構成、生成コードと追加した処理の関係、変更したい動作を、分かる範囲でお知らせください。

    支援内容は、Qt に関する SRA のサービスをご覧ください。