PyQt

【PyQt】コンテナウィジェットの使い方

【PyQt】コンテナウィジェットの使い方 QTabWidget QGroupBox

PythonのGUIツールキットであるPyQtで画面要素であるコンテナウィジェットの使い方について解説します。

コンテナウィジェットの使い方

PyQtでは、画面作成のために様々なウィジェットを使用することができますが、複数のウィジェットをまとめて入れられるコンテナウィジェットというものがあります。

具体的にはタブで画面を切り替えられるようにするQTabWidgetとウィジェットをグループとしてまとめて表示できるQGroupBoxがあります。

本記事では、コンテナウィジェットであるQTabWidgetとQGroupBoxについて使用例を用いて使い方を説明します。

タブウィジェット QTabWidget

GUIアプリケーションでは、目的ごとにタブで機能を切り替えられるようになっている画面があると思います。PyQtでタブを表現するためにはQTabWidgetを使用できます。QTabWidgetの使い方の流れとしては以下のようになります。

  1. QTabWidgetオブジェクトを生成する。
  2. QWidget又はその他ウィジェットクラス上にUIを作成する。
  3. QTabWidget.addTab()メソッドでUIを追加する。

では、具体的なソースコードサンプルでQTabWidgetの使い方を見てみましょう。

import sys

from PyQt6 import QtCore as qtc
from PyQt6 import QtGui as qtg
from PyQt6 import QtWidgets as qtw


class MainWindow(qtw.QWidget):
    """メインウィンドウ"""

    def __init__(self):
        super().__init__()
        # 画面タイトルの設定
        self.setWindowTitle("QTabWidget")
        # 画面サイズの設定
        self.resize(640, 360)

        # メインレイアウトの設定
        main_layout = qtw.QVBoxLayout()
        self.setLayout(main_layout)

        # ===== Tab1 の用意
        tab1 = qtw.QWidget(self)
        # タブ内のウィジェットの生成
        label = qtw.QLabel("Tab 1", self)
        line_edit = qtw.QLineEdit(self, placeholderText="入力してください。")
        checkbox = qtw.QCheckBox("チェック", self)
        button = qtw.QPushButton("登録", self)
        # タブ内のレイアウトの作成
        tab1_layout = qtw.QVBoxLayout()
        tab1.setLayout(tab1_layout)
        # ウィジェット配置
        tab1_layout.addWidget(label)
        tab1_layout.addWidget(line_edit)
        tab1_layout.addWidget(checkbox)
        tab1_layout.addWidget(button)
        tab1_layout.addStretch()

        # ===== Tab2 の用意
        tab2 = qtw.QWidget(self)
        # タブ内のウィジェットの生成
        label_2 = qtw.QLabel("Tab 2", self)
        text_edit_2 = qtw.QTextEdit(self)
        button_2 = qtw.QPushButton("登録", self)
        # タブ内のレイアウトの作成
        tab2_layout = qtw.QVBoxLayout()
        tab2.setLayout(tab2_layout)
        # ウィジェット配置
        tab2_layout.addWidget(label_2)
        tab2_layout.addWidget(text_edit_2)
        tab2_layout.addWidget(button_2)

        # ===== Tabウィジェットの用意
        tab_widget = qtw.QTabWidget(
            movable=True,
            tabPosition=qtw.QTabWidget.TabPosition.North,
            tabShape=qtw.QTabWidget.TabShape.Rounded,
        )
        # タブにウィジェットを追加
        tab_widget.addTab(tab1, "タブ 1")
        tab_widget.addTab(tab2, "タブ 2")

        # メインレイアウトに追加
        main_layout.addWidget(tab_widget)

        # 画面表示
        self.show()


def main():
    """メイン関数"""
    app = qtw.QApplication(sys.argv)
    mv = MainWindow()
    sys.exit(app.exec())


if __name__ == "__main__":
    main()

【タブ1】

QTabWidget 例

【タブ2】

QTabWidget 例

【詳細説明】

画面全体のプログラムの構造は「QWidgetを継承した画面開発のテンプレート」をベースにしていますので説明は省略し、QTabWidgetの使用部分のみ説明します。興味がある方は上記ページもご確認ください。

        # ===== Tab1 の用意
        tab1 = qtw.QWidget(self)
        # タブ内のウィジェットの生成
        label = qtw.QLabel("Tab 1", self)
        line_edit = qtw.QLineEdit(self, placeholderText="入力してください。")
        checkbox = qtw.QCheckBox("チェック", self)
        button = qtw.QPushButton("登録", self)
        # タブ内のレイアウトの作成
        tab1_layout = qtw.QVBoxLayout()
        tab1.setLayout(tab1_layout)
        # ウィジェット配置
        tab1_layout.addWidget(label)
        tab1_layout.addWidget(line_edit)
        tab1_layout.addWidget(checkbox)
        tab1_layout.addWidget(button)
        tab1_layout.addStretch()

上記の部分はタブ1の内容を定義している部分です。まず、タブ1用のQWidgetをtab1としてオブジェクト化して、ラベルなどのタブ内のウィジェットを用意します。

タブ内のレイアウトを作成してtab1にsetLayoutで設定します。今回の例では、QVBoxLayoutを使用していますがレイアウトについては他にもありますので「ウィジェットのレイアウト方法」を参考にして設定ください。後は、用意したラベルなどのウィジェットをレイアウトにaddWidgetで追加していきます。

        # ===== Tab2 の用意
        tab2 = qtw.QWidget(self)
        # タブ内のウィジェットの生成
        label_2 = qtw.QLabel("Tab 2", self)
        text_edit_2 = qtw.QTextEdit(self)
        button_2 = qtw.QPushButton("登録", self)
        # タブ内のレイアウトの作成
        tab2_layout = qtw.QVBoxLayout()
        tab2.setLayout(tab2_layout)
        # ウィジェット配置
        tab2_layout.addWidget(label_2)
        tab2_layout.addWidget(text_edit_2)
        tab2_layout.addWidget(button_2)

上記の部分はタブ2の内容を定義している部分です。用意の方法としてはタブ1と同様です。さらにタブを作りたい場合は同様にタブの定義を用意します。

       # ===== Tabウィジェットの用意
        tab_widget = qtw.QTabWidget(
            movable=True,
            tabPosition=qtw.QTabWidget.TabPosition.North,
            tabShape=qtw.QTabWidget.TabShape.Rounded,
        )
        # タブにウィジェットを追加
        tab_widget.addTab(tab1, "タブ 1")
        tab_widget.addTab(tab2, "タブ 2")

        # メインレイアウトに追加
        main_layout.addWidget(tab_widget)

上記がQTabWidgetを作成している部分です。引数としては以下のような項目が設定できます。

  • movable: Trueにするとタブの順番をマウスで入れ替えることができるようになります。
  • tabPosition: タブの位置を指定します。North, South, East, Westが指定できるので画面の上下左右どこにタブを出すのか指定できます。
  • tabShape: タブの形状を指定します。Roundedの他にTriangularを指定することができ、タブの形状を変えることもできます。

Tabウィジェットを用意したら上記で説明したように用意したタブ(tab1やtab2)をaddTabでQTabWidgetに追加します。最後にメイン画面レイアウトにQTabWidgetを追加します。

なお、tabShape=qtw.QTabWidget.TabShape.Triangularにすると以下のようなタブ形状になります。

QTabWidget 例

グループボックス QGroupBox

複数のウィジェットのまとまりが分かるようにグループ化する際には、QGroupBoxを使用できます。QGroupBoxの使い方の流れとしては以下のようになります。

  1. QGroupBoxオブジェクトを生成する。
  2. GroupBox内のレイアウトを作成し、QGroupBoxオブジェクトにsetLayoutで設定する。
  3. レイアウトにグループ化したいウィジェットをaddWidgetを使って追加する。

では、具体的なソースコードサンプルでQGroupBoxの使い方を見てみましょう。

import sys

from PyQt6 import QtCore as qtc
from PyQt6 import QtGui as qtg
from PyQt6 import QtWidgets as qtw


class MainWindow(qtw.QWidget):
    """メインウィンドウ"""

    def __init__(self):
        super().__init__()
        # 画面タイトルの設定
        self.setWindowTitle("QGroupWidget")
        # 画面サイズの設定
        self.resize(640, 360)

        # メインレイアウトの設定
        main_layout = qtw.QVBoxLayout()
        self.setLayout(main_layout)

        # GroupBoxウィジェットの用意
        groupbox = qtw.QGroupBox(
            "ボタンリスト",
            checkable=False,
            checked=False,
            alignment=qtc.Qt.AlignmentFlag.AlignLeft,
            flat=False,
        )
        group_layout = qtw.QHBoxLayout()
        groupbox.setLayout(group_layout)
        group_layout.addWidget(qtw.QPushButton("登録"))
        group_layout.addWidget(qtw.QPushButton("更新"))
        group_layout.addWidget(qtw.QPushButton("削除"))

        # メインレイアウトに追加
        main_layout.addWidget(groupbox)
        main_layout.addStretch()

        # 画面表示
        self.show()


def main():
    """メイン関数"""
    app = qtw.QApplication(sys.argv)
    mv = MainWindow()
    sys.exit(app.exec())


if __name__ == "__main__":
    main()

【表示結果】

QGroupBox 例

【詳細説明】

画面全体のプログラムの構造は「QWidgetを継承した画面開発のテンプレート」をベースにしていますので説明は省略し、QGroupBoxの使用部分のみ説明します。興味がある方は上記ページもご確認ください。

       # GroupBoxウィジェットの用意
        groupbox = qtw.QGroupBox(
            "ボタンリスト",
            checkable=False,
            checked=False,
            alignment=qtc.Qt.AlignmentFlag.AlignLeft,
            flat=False,
        )
        group_layout = qtw.QHBoxLayout()
        groupbox.setLayout(group_layout)
        group_layout.addWidget(qtw.QPushButton("登録"))
        group_layout.addWidget(qtw.QPushButton("更新"))
        group_layout.addWidget(qtw.QPushButton("削除"))

まずはGroupBoxのウィジェットをオブジェクト化します。その際に、グループ名の文字列を第1引数に指定します。その他の引数としては以下の通りです。

  • checkable: Trueにするとチェックボックスによりグループ内のウィジェットを有効/無効にすることができます。
  • checked: checkableと合わせて使用し、Trueにすると表示時にチェック状態で表示されます。
  • alignment: グループ名の文字列の配置を指定します。AlignLeft, AlignHCenter, AlignRightといったものが使えます。
  • flat: グループを囲いではなく線で表現します。

checkableをTrueにすると以下のようにチェックボックスが表示されます。チェックしていない場合は内部のウィジェットが無効化されたような状態で表示されます。

QGroupBox 例

チェックボックスにチェックすると以下のようにグループ内のウィジェットが有効化されます。checked引数をTrueにした場合は、以下の状態で画面が初期表示されます。

QGroupBox 例

flat=Trueにした場合は以下のような表現になります。

QGroupBox 例

上記の引数は組み合わせて使えますので、お好みの表現を使用してもらえればと思います。

まとめ

PythonのGUIツールキットであるPyQtで画面要素であるコンテナウィジェットの使い方について解説しました。

具体的にはタブで画面を切り替えられるようにするQTabWidgetとウィジェットをグループとしてまとめて表示できるQGroupBoxの使い方を紹介しています。

どちらも画面の表現力を向上させてくれる便利なウィジェットなので是非使ってもらえるとよいかと思います。