PyQt5ウィジェットとレイアウトの基本

ボタン

btn = QPushButton("ボタン")

ボタンクリックイベント

btn.clicked.connect(関数名)  # 括弧は不要

ラジオボタン

rbtn = QRadioButton("オプション")

ラベル

label = QLabel("ラベル: ")

入力フィールド

# 入力ボックス
edit = QLineEdit(None)  # 親ウィジェット
edit.setPlaceholderText("プレースホルダー")

グループボックス

group = QGroupBox("グループ")

レイアウト

ボックスレイアウト

垂直レイアウト

layout = QVBoxLayout()

ストレッチャー(スペーサー)

layout.addStretch(1)

垂直レイアウトの例

import sys
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget, QPushButton, QGroupBox, QMainWindow
from PyQt5.QtCore import Qt


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        
        self.resize(400, 400)
        self.setWindowTitle("垂直レイアウトの例")
        
        layout = QVBoxLayout()
        
        # ストレッチを追加してスペースを調整
        # 比率は1:1:1:2
        layout.addStretch(1)
        
        # ボタン1
        button1 = QPushButton("ボタン1")
        layout.addWidget(button1)
        
        layout.addStretch(1)
        
        # ボタン2
        button2 = QPushButton("ボタン2")
        layout.addWidget(button2)
        
        layout.addStretch(1)
        
        # ボタン3
        button3 = QPushButton("ボタン3")
        layout.addWidget(button3)
        
        layout.addStretch(2)
        
        self.setLayout(layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    app.exec_()

水平レイアウト

h_layout = QHBoxLayout()

レイアウトのネスト例

import sys
from PyQt5.QtWidgets import *


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.resize(350, 250)
        
        main_layout = QVBoxLayout()
        
        # 趣味グループ
        hobby_group = QGroupBox("趣味")
        hobby_layout = QVBoxLayout()
        
        btn_smoke = QPushButton("喫煙")
        btn_drink = QPushButton("飲酒")
        btn_code = QPushButton("プログラミング")
        
        hobby_layout.addWidget(btn_smoke)
        hobby_layout.addWidget(btn_drink)
        hobby_layout.addWidget(btn_code)
        hobby_group.setLayout(hobby_layout)
        
        # 性別グループ
        gender_group = QGroupBox("性別")
        gender_layout = QHBoxLayout()
        
        radio_male = QRadioButton("男性")
        radio_female = QRadioButton("女性")
        
        gender_layout.addWidget(radio_male)
        gender_layout.addWidget(radio_female)
        gender_group.setLayout(gender_layout)
        
        main_layout.addWidget(hobby_group)
        main_layout.addWidget(gender_group)
        
        self.setLayout(main_layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    app.exec_()

グリッドレイアウト

グリッドレイアウトの宣言

grid = QGridLayout()

グリッドレイアウトの例(電卓インターフェース)

import sys
from PyQt5.QtWidgets import *


class CalculatorWindow(QWidget):
    def __init__(self):
        super().__init__()
        
        container = QVBoxLayout()
        
        # ディスプレイ
        display = QLineEdit()
        display.setPlaceholderText("数値を入力")
        container.addWidget(display)
        
        # ボタングリッド
        grid = QGridLayout()
        
        button_data = {
            0: {"7", "8", "9", "+"},
            1: {"4", "5", "6", "-"},
            2: {"3", "2", "1", "*"},
            3: {"0", ".", "=", "/"}
        }
        
        for row, row_data in button_data.items():
            for col, text in enumerate(row_data):
                button = QPushButton(text)
                grid.addWidget(button, row, col)
        
        container.addLayout(grid)
        self.setLayout(container)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = CalculatorWindow()
    window.show()
    app.exec_()

ウィンドウの中央表示とアイコン設定

import sys
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import *
from PyQt5.QtWidgets import QDesktopWidget


if __name__ == '__main__':
    app = QApplication(sys.argv)
    
    window = QWidget()
    window.setWindowTitle("PyQt5 基礎")
    window.resize(320, 320)
    
    # 画面中央に配置
    screen_center = QDesktopWidget().availableGeometry().center()
    x = screen_center.x()
    y = screen_center.y()
    rect = window.frameGeometry().getRect()
    window.move(x - rect[2]//2, y - rect[3]//2)
    
    # アイコン設定
    window.setWindowIcon(QIcon('icon.png'))
    
    # ボタン
    button = QPushButton("クリック")
    button.setParent(window)
    
    # ラベル
    label = QLabel("テキスト", window)
    label.setGeometry(30, 30, 50, 30)
    
    # 入力フィールド
    input_field = QLineEdit(window)
    input_field.setPlaceholderText("プレースホルダー")
    input_field.setGeometry(30, 70, 120, 30)
    
    window.show()
    app.exec_()

フォームレイアウト(ログイン画面)

フォームレイアウト

form_layout = QFormLayout()

フォームレイアウトの例

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QVBoxLayout, QFormLayout, QLineEdit, QPushButton, QApplication, QWidget


class LoginWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setup_ui()

    def setup_ui(self):
        self.setFixedSize(320, 180)
        
        container = QVBoxLayout()
        
        form = QFormLayout()
        
        # ユーザー名入力
        username = QLineEdit()
        username.setPlaceholderText("ユーザー名を入力")
        form.addRow("ユーザー名:", username)
        
        # パスワード入力
        password = QLineEdit()
        password.setPlaceholderText("パスワードを入力")
        form.addRow("パスワード:", password)
        
        container.addLayout(form)
        
        # ログインボタン
        login_button = QPushButton("ログイン")
        login_button.setFixedSize(100, 35)
        container.addWidget(login_button, alignment=Qt.AlignRight)
        
        self.setLayout(container)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = LoginWindow()
    window.show()
    app.exec_()

スタックレイアウト(タブ切り替え)

スタックレイアウトの宣言

stacked_layout = QStackedLayout()

特定のパネルを表示

stacked_layout.setCurrentIndex(0)

スタックレイアウトの例

import sys
from PyQt5.QtWidgets import *


class Panel1(QWidget):
    def __init__(self):
        super().__init__()
        QLabel("パネル1", self)


class Panel2(QWidget):
    def __init__(self):
        super().__init__()
        QLabel("パネル2", self)


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.resize(400, 300)
        self.stacked_layout = QStackedLayout()
        self.create_panels()
        self.setup_ui()

    def create_panels(self):
        panel1 = Panel1()
        panel2 = Panel2()
        
        self.stacked_layout.addWidget(panel1)
        self.stacked_layout.addWidget(panel2)

    def setup_ui(self):
        container = QVBoxLayout()
        panel_widget = QWidget()
        panel_widget.setLayout(self.stacked_layout)
        
        btn_panel1 = QPushButton("パネル1表示")
        btn_panel2 = QPushButton("パネル2表示")
        
        btn_panel1.clicked.connect(self.show_panel1)
        btn_panel2.clicked.connect(self.show_panel2)
        
        container.addWidget(panel_widget)
        container.addWidget(btn_panel1)
        container.addWidget(btn_panel2)
        
        self.setLayout(container)

    def show_panel1(self):
        print("パネル1を表示")
        self.stacked_layout.setCurrentIndex(0)

    def show_panel2(self):
        print("パネル2を表示")
        self.stacked_layout.setCurrentIndex(1)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    app.exec_()

タグ: PyQt5 Python GUI Qt レイアウト

8月7日 12:58 投稿