Qt をはじめよう! 第14回: GUI デザイナでのレイアウトに慣れよう!

今回は GUI デザイナを通して、UI を作成する際に使用する様々なレイアウトについて学びましょう。

今回も新たにプロジェクトを作成しましょう。

  • テンプレートは「Qt GUI アプリケーション」を選択してください。
  • プロジェクトのパスと名前は任意の名前を指定してください。
  • 基底クラスは「QWidget」で、クラス名の所は今回はデフォルトのまま「Widget」にします。
    • 「フォームを生成する」のチェックは外さないでください。

プロジェクトの作成方法は 第13回 と同様ですので、詳細はそちらを参照してください。

様々なレイアウトを使用する

レイアウト管理を学ぼう で紹介したとおり Qt では4つのレイアウトが標準で利用できます。GUI デザイナでもこれらのレイアウトを使用する事が可能です。

  • [qt QVBoxLayout] を使用すると複数のウィジェットやレイアウトを縦方向に並べることができます。

  • [qt QHBoxLayout] を使用すると複数のウィジェットやレイアウトを横方向に並べることができます。

  • [qt QGridLayout] を使用すると複数のウィジェットやレイアウトをグリッド状に並べることができます。

  • [qt QFormLayout] は入力ウィジェットをラベルとセットにして複数並べるためのレイアウトです。同様のレイアウトは QGridLayout でも基本的には可能ですが、QFormLayout では一般的な入力フォーム向けに [qt "レイアウトが最適化" l=qformlayout m=#details] されます。

レイアウトを設定する

GUI デザイナでのレイアウトの設定方法は2種類あります。ウィジェットに対してレイアウトを設定する場合と、複数のウィジェットをレイアウトでまとめるだけの場合です。ウィジェットに対してレイアウトを設定した場合は、そのウィジェットのサイズに応じて動的にレイアウトが更新されます。一方、レイアウトを作成しただけの場合にはそのような動的な更新は行われません。このレイアウトは他のレイアウトやウィジェットを組み合わせて複雑なレイアウトを実現する為に使用します。

それではこの2つの違いを実際に確認してみましょう。

以下のように「Line Edit」と「Text Edit」をフォーム上に配置してください。

この2つの子ウィジェットを親ウィジェット(ここではフォーム「Widget」)にレイアウトする場合には、以下のようにそのウィジェット自身を選択した状態でレイアウトを設定します。

ツール(T) -> フォーム エディタ(M) -> Preview… からプレビュー画面を表示し、ウインドウのサイズを変えた際にレイアウトがそのサイズに応じて変わる事を確認してみてください。

上記の例では QWidget に対してレイアウトを設定しましたが、「Containers」グループにあるような子ウィジェットを含む目的で使用されるその他のウィジェットの場合も、それらのウィジェットに対してレイアウトを設定することが可能です。

逆に、単にこの2つのウィジェットを並べるためにレイアウトを使用したい場合には、対象となるウィジェットを選択した状態でレイアウトを設定します。

この場合は、親ウィジェット自体にはレイアウトが設定されておらず、新たなレイアウトクラスが生成され、その中に2つのウィジェットが含まれています。親ウィジェットにレイアウトが設定されていないため、ウィンドウのサイズが変わってもこのレイアウトの大きさは自動的には再計算されません。こちらもプレビューを表示してウィンドウのサイズを変えても子ウィジェットの位置や大きさが変わらない事を確認してみてください。

レイアウトを組み合わせて使用する

複数のレイアウトを組み合わせて下記のようなデザインを作成する方法を見てみましょう。

Label を3つと Line Edit を2つ、Text Edit を1つ、Button Box を1つ使用します。この際、最終レイアウトに近い並びになるように各ウィジェットを配置してください。

次に、ラベルと入力ウィジェットを選択し、QFormLayout を設定します。
次に、フォームを選択し、QFormLayout と Button Box をフォーム全体に垂直方向にレイアウトします。

このように、複数のレイアウトを組み合わせて利用する事により、複雑なユーザーインタフェースをデザインすることができます。

GUI デザイナで複雑なレイアウトの UI を作成する際には最初に全てのウィジェットをある程度正しい位置に配置し、小さい単位からレイアウトを設定していき、最後に親ウィジェットにそれらを組み合わせたレイアウトを設定するとよいでしょう。先に親ウィジェットにレイアウトを設定してしまうと、その後に配置する全ての子ウィジェットや子レイアウトがそのレイアウトの中に入ってしまうため、デザインがしにくくなります。また、既存のデザインを修正する際も修正箇所より上位のレイアウトを一度解除すると作業がしやすくなるでしょう。

今回はデザインを作成する際に [qt QFormLayout] と [qt "Button Box" l=qdalogbuttonbox ] を使用しました。この2つのクラスは各プラットフォームに応じて最適な表示を行うように実装されています。

ラベルの文字を「To:」、「Subject:」、「Body:」のように変更すると Mac では Mac のスタイルガイドに合わせて右寄せの表示になります。また、ボタンの配置も Mac では「キャンセル」、「OK」の順番で並んでいますが、これもプラットフォームやプラットフォーム上のスタイルに応じて自動的に表示の順番が変わります。

また、この2つのクラスは右から左へのレイアウトにも対応しています。

Widget の [qt "layoutDirection" l=qwidget m=#layoutDirection-prop] プロパティを「[qt "RightToLeft" l=qt m=#LayoutDirection-enum]」に変更してプレビューを表示してみてください。ラベルと入力ウィジェットの左右が入れ替わり、ボタンも左寄せになります。

このように、これらのクラスを使用することで、複数のプラットフォームや言語の対応がより簡単にできるようになります。

レイアウトの調整

レイアウトの中で空間をあけたい場合には「Spacers」の中にある「[qt "Vertical Spacer" l=qspaceritem]」、「[qt "Horizontal Spacer" l=qspaceritem]」を使用してください。これによりレイアウトの中にスペースを作成することが出来ます。ウィジェットを右寄せや左寄せしたい場合などに使います。

それぞれのレイアウトにはマージンやスペース等のプロパティを持っていて細かい調整ができるようになっています。マージンはレイアウトの周囲の幅の調整、スペースはレイアウト中のウィジェット間の距離の調整に使用します。

以下の図は Frame に Line Edit と Text Edit を垂直方向にレイアウトしたものを左右に置いています。
左側はレイアウトのマージンとスペースがデフォルトの値の場合で、右側はマージンとスペースをそれぞれ 0 に設定した場合です。右側の場合は親ウィジェットいっぱいに子ウィジェットが配置され、ウィジェット間のスペースも無くなっています。

その他にも [qt QWidget sizePolicy m=#sizePolicy-prop] の設定や [qt QBoxLayout setStretch] 等によってもレイアウトを調整する事が可能です。

おわりに

今回は GUI デザイナを使用した UI のレイアウトについて学びました。Qt のレイアウト管理は非常に強力な機能ですが、GUI デザイナ上で様々なデザインを実現するには多少の慣れも必要かと思います。実際に色々な UI を作成してみて、GUI デザイナを使いこなせるせるようになってください。


Blog Topics:

Comments