PyQt5 FormLayoutの自動伸縮設定


概要

PyQt5でフォーム画面を作成する際に解決まで時間がかかったことの記載

やりたいこと

入力欄が画面いっぱいに伸びているフォームの作成

困ったこと

Widgetによって幅がバラバラになってしまう。setSizePolicyでwidgetの伸縮設定を変更しても期待した様にならなかった。

SizePolicyの参考記事
QSizePolicy Class | Qt Widgets 5.15.2
ウィジェットの自動伸縮の設定 - yu00’s blog

解決策

QFormLayout.setFieldGrowthPolicyでフォームレイアウトの伸縮設定を変更
QFormLayout Class | Qt Widgets 5.15.2

環境

  • Mac OS
  • Python 3.8.5
  • PyQt5 5.12.2
  • PyQt5-sip 12.8.1

詳細

pip install

pip install PyQt5
pip install PyQt5-sip
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt


class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Form Layout")
        self.setGeometry(350, 150, 400, 400)
        self.ui()

        self.show()

    def ui(self) -> None:
        """UI作成"""
        self.main_design()
        self.layouts()

    def main_design(self) -> None:
        """widget作成"""
        # main_layoutで使用
        self.title = QLabel("Add Person")
        self.title.setStyleSheet("font-size: 24pt;")

        # form_layoutで使用
        self.name_lable = QLabel("Name :")
        self.name_entry = QLineEdit()
        self.surname_lable = QLabel("Surname :")
        self.surname_entry = QLineEdit()
        self.phone_lable = QLabel("Phone :")
        self.phone_entry = QLineEdit()
        self.email_lable = QLabel("Email :")
        self.email_entry = QLineEdit()
        self.img_label = QLabel("Picture :")
        self.img_button = QPushButton("Browse")
        self.address_lable = QLabel("Address :")
        self.address_entry = QTextEdit()
        self.add_button = QPushButton("Add")

    def layouts(self) -> None:
        """レイアウトの作成 & 編集"""
        # 使用するレイアウトを作成
        self.main_layout = QVBoxLayout()
        self.form_layout = QFormLayout()
        self.form_layout.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow)

        # main_layoutにwidgetとform_layoutを追加
        self.main_layout.addWidget(self.title, alignment=Qt.AlignHCenter)
        self.main_layout.addLayout(self.form_layout)

        # form_layoutにwidget追加
        self.form_layout.addRow(self.name_lable, self.name_entry)
        self.form_layout.addRow(self.surname_lable, self.surname_entry)
        self.form_layout.addRow(self.phone_lable, self.phone_entry)
        self.form_layout.addRow(self.email_lable, self.email_entry)
        self.form_layout.addRow(self.img_label, self.img_button)
        self.form_layout.addRow(self.address_lable, self.address_entry)
        self.form_layout.addRow("", self.add_button)

        # 画面にmain_layoutを適応
        self.setLayout(self.main_layout)


def main():
    App = QApplication(sys.argv)
    window = Window()
    sys.exit(App.exec_())


if __name__ == "__main__":
    main()

重要なのはdef layouts内のself.form_layout.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow)

QFormLayout Class | Qt Widgets 5.15.2

Constant Value Description
QFormLayout::FieldsStayAtSizeHint 0 The fields never grow beyond their effective size hint. This is the default for QMacStyle.
QFormLayout::ExpandingFieldsGrow 1 Fields with an horizontal size policy of Expanding or MinimumExpanding will grow to fill the available space. The other fields will not grow beyond their effective size hint. This is the default policy for Plastique.
QFormLayout::AllNonFixedFieldsGrow 2 All fields with a size policy that allows them to grow will grow to fill the available space. This is the default policy for most styles.

大体の訳

  • FieldsStayAtSizeHint:伸縮無し, Macの時はこれがデフォルト
  • ExpandingFieldsGrow:水平方向のSizePolicyがExpandingMinimumExpandingのwidgetは伸縮する
  • AllNonFixedFieldsGrow:伸縮が許可されている全てのwidgetは伸縮する

valueで設定してもOK

self.form_layout.setFieldGrowthPolicy(2)

参考記事

SizePolicy
QSizePolicy Class | Qt Widgets 5.15.2
ウィジェットの自動伸縮の設定 - yu00’s blog

QFormLayout.setFieldGrowthPolicy
QFormLayout Class | Qt Widgets 5.15.2