0
2

PySideで始めるPython GUI開発入門

Last updated at Posted at 2024-09-02

はじめに

PySideは、PythonでGUIアプリケーションを開発するための強力なツールキットです。QtフレームワークをPythonから利用できるようにしたもので、直感的なAPIと豊富な機能を提供します。この記事では、PySideを使ったGUI開発の基礎から応用までを15章に分けて解説します。

第1章: PySideのインストールと基本設定

まずはPySideをインストールしましょう。以下のコマンドでPySide6をインストールできます:

pip install PySide6

インストールが完了したら、以下の簡単なコードで動作確認をしてみましょう:

import sys
from PySide6.QtWidgets import QApplication, QLabel

app = QApplication(sys.argv)
label = QLabel("こんにちは、PySide!")
label.show()
sys.exit(app.exec())

このコードを実行すると、「こんにちは、PySide!」というテキストを表示する小さなウィンドウが表示されます。

第2章: ウィンドウの作成

GUIアプリケーションの基本はウィンドウです。以下のコードで、タイトルとサイズを指定したウィンドウを作成できます:

import sys
from PySide6.QtWidgets import QApplication, QMainWindow

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("私の最初のPySideアプリ")
        self.setGeometry(100, 100, 300, 200)

app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())

このコードでは、QMainWindowクラスを継承して独自のウィンドウクラスを定義しています。setWindowTitle()でウィンドウのタイトルを、setGeometry()でウィンドウの位置とサイズを設定しています。

第3章: ボタンの追加

ウィンドウにボタンを追加してみましょう:

import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("ボタン付きウィンドウ")
        self.setGeometry(100, 100, 300, 200)

        button = QPushButton("クリックしてね", self)
        button.setGeometry(100, 80, 100, 30)
        button.clicked.connect(self.button_clicked)

    def button_clicked(self):
        print("ボタンがクリックされました!")

app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())

このコードでは、QPushButtonを使ってボタンを作成し、clickedシグナルをbutton_clickedメソッドに接続しています。ボタンがクリックされると、コンソールにメッセージが表示されます。

第4章: レイアウトの使用

ウィジェットを整列させるには、レイアウトを使用するのが便利です。以下はQVBoxLayoutを使用した例です:

import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("レイアウトの例")

        layout = QVBoxLayout()
        
        button1 = QPushButton("ボタン1")
        button2 = QPushButton("ボタン2")
        button3 = QPushButton("ボタン3")

        layout.addWidget(button1)
        layout.addWidget(button2)
        layout.addWidget(button3)

        central_widget = QWidget()
        central_widget.setLayout(layout)
        self.setCentralWidget(central_widget)

app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())

この例では、QVBoxLayoutを使って3つのボタンを縦に配置しています。

第5章: テキスト入力

ユーザーからの入力を受け取るために、QLineEditウィジェットを使用できます:

import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QLineEdit, QPushButton, QVBoxLayout, QWidget

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("テキスト入力")

        layout = QVBoxLayout()

        self.text_input = QLineEdit()
        self.button = QPushButton("送信")
        self.button.clicked.connect(self.on_button_click)

        layout.addWidget(self.text_input)
        layout.addWidget(self.button)

        central_widget = QWidget()
        central_widget.setLayout(layout)
        self.setCentralWidget(central_widget)

    def on_button_click(self):
        print(f"入力されたテキスト: {self.text_input.text()}")

app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())

このコードでは、QLineEditを使ってテキスト入力フィールドを作成し、ボタンがクリックされたときに入力されたテキストを表示します。

第6章: メッセージボックス

ユーザーに情報を表示したり、確認を求めたりするためのメッセージボックスを作成できます:

import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QMessageBox

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("メッセージボックスの例")

        button = QPushButton("メッセージを表示", self)
        button.setGeometry(50, 50, 200, 30)
        button.clicked.connect(self.show_message)

    def show_message(self):
        msg_box = QMessageBox()
        msg_box.setWindowTitle("情報")
        msg_box.setText("これはメッセージボックスです。")
        msg_box.setIcon(QMessageBox.Information)
        msg_box.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
        
        result = msg_box.exec()
        if result == QMessageBox.Ok:
            print("OKが押されました")
        else:
            print("キャンセルが押されました")

app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())

この例では、ボタンをクリックするとメッセージボックスが表示され、ユーザーの選択に応じて異なる処理を行います。

第7章: メニューバーとツールバー

アプリケーションにメニューバーとツールバーを追加することで、より多くの機能にアクセスしやすくなります:

import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QAction, QToolBar
from PySide6.QtGui import QIcon

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("メニューとツールバーの例")

        # メニューバーの作成
        menu_bar = self.menuBar()
        file_menu = menu_bar.addMenu("ファイル")
        edit_menu = menu_bar.addMenu("編集")

        # アクションの作成
        new_action = QAction("新規", self)
        new_action.setShortcut("Ctrl+N")
        new_action.triggered.connect(self.new_file)

        open_action = QAction("開く", self)
        open_action.setShortcut("Ctrl+O")
        open_action.triggered.connect(self.open_file)

        # メニューにアクションを追加
        file_menu.addAction(new_action)
        file_menu.addAction(open_action)

        # ツールバーの作成
        toolbar = QToolBar()
        self.addToolBar(toolbar)
        toolbar.addAction(new_action)
        toolbar.addAction(open_action)

    def new_file(self):
        print("新規ファイルが選択されました")

    def open_file(self):
        print("ファイルを開くが選択されました")

app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())

この例では、メニューバーとツールバーを作成し、それぞれにアクションを追加しています。

第8章: ダイアログ

ダイアログを使用して、ユーザーとのインタラクションを強化できます:

import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QDialog, QVBoxLayout, QLabel, QLineEdit

class CustomDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("カスタムダイアログ")

        layout = QVBoxLayout()
        self.label = QLabel("名前を入力してください:")
        self.input = QLineEdit()
        self.button = QPushButton("OK")
        self.button.clicked.connect(self.accept)

        layout.addWidget(self.label)
        layout.addWidget(self.input)
        layout.addWidget(self.button)

        self.setLayout(layout)

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("ダイアログの例")

        button = QPushButton("ダイアログを開く", self)
        button.setGeometry(50, 50, 200, 30)
        button.clicked.connect(self.show_dialog)

    def show_dialog(self):
        dialog = CustomDialog(self)
        if dialog.exec() == QDialog.Accepted:
            name = dialog.input.text()
            print(f"こんにちは、{name}さん!")

app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())

この例では、カスタムダイアログを作成し、メインウィンドウから呼び出しています。

第9章: テーブルとリスト

データを表形式で表示するには、QTableWidgetQListWidgetが便利です:

import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QTableWidget, QTableWidgetItem, QVBoxLayout, QWidget

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("テーブルの例")

        layout = QVBoxLayout()

        table = QTableWidget(5, 3)
        table.setHorizontalHeaderLabels(["名前", "年齢", "職業"])

        data = [
            ("田中太郎", "30", "エンジニア"),
            ("佐藤花子", "25", "デザイナー"),
            ("鈴木一郎", "40", "マネージャー"),
            ("高橋美咲", "35", "営業"),
            ("伊藤健太", "28", "研究員")
        ]

        for row, (name, age, job) in enumerate(data):
            table.setItem(row, 0, QTableWidgetItem(name))
            table.setItem(row, 1, QTableWidgetItem(age))
            table.setItem(row, 2, QTableWidgetItem(job))

        layout.addWidget(table)

        central_widget = QWidget()
        central_widget.setLayout(layout)
        self.setCentralWidget(central_widget)

app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())

この例では、QTableWidgetを使用してデータをテーブル形式で表示しています。

第10章: グラフィックスとアニメーション

PySideを使用して、グラフィックスやアニメーションを作成することもできます:

import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QGraphicsView, QGraphicsScene, QGraphicsEllipseItem
from PySide6.QtCore import QTimer, QPropertyAnimation, QEasingCurve
from PySide6.QtGui import QPen, QBrush, QColor

class AnimatedCircle(QGraphicsEllipseItem):
    def __init__(self, x, y, r):
        super().__init__(0, 0, r*2, r*2)
        self.setPos(x, y)
        self.setBrush(QBrush(QColor(255, 0, 0)))

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("アニメーションの例")

        self.scene = QGraphicsScene()
        self.view = QGraphicsView(self.scene)
        self.setCentralWidget(self.view)

        self.circle = AnimatedCircle(0, 0, 20)
        self.scene.addItem(self.circle)

        self.animation = QPropertyAnimation(self.circle, b"pos")
        self.animation.setDuration(2000)
        self.animation.setStartValue(self.circle.pos())
        self.animation.setEndValue(self.circle.pos() + self.circle.pos().transposed())
        self.animation.setEasingCurve(QEasingCurve.InOutQuad)

        self.timer = QTimer()
        self.timer.timeout.connect(self.start_animation)
        self.timer.start(3000)

    def start_animation(self):
        self.animation.start()

app = QApplication(sys.argv)
window = MainWindow()
window.setGeometry(100, 100, 300, 300)
window.show()
sys.exit(app.exec())

第11章: イベント処理

PySideでは、イベント処理を通じてユーザーのアクションに応答できます。以下は、マウスイベントを処理する例です:

import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QLabel
from PySide6.QtCore import Qt

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("イベント処理の例")

        self.label = QLabel("ここにマウスの位置が表示されます", self)
        self.label.setAlignment(Qt.AlignCenter)
        self.setCentralWidget(self.label)

    def mouseMoveEvent(self, event):
        x = event.x()
        y = event.y()
        self.label.setText(f"マウスの位置: ({x}, {y})")

app = QApplication(sys.argv)
window = MainWindow()
window.setGeometry(100, 100, 400, 300)
window.show()
sys.exit(app.exec())

このコードでは、mouseMoveEventメソッドをオーバーライドして、マウスの位置を取得し、ラベルに表示しています。

第12章: データバインディング

データバインディングを使用すると、モデルとビューを連携させてデータを表示できます。以下は、QListViewQStringListModelを使用した例です:

import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QListView, QVBoxLayout, QWidget
from PySide6.QtCore import QStringListModel

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("データバインディングの例")

        layout = QVBoxLayout()

        self.list_view = QListView()
        self.model = QStringListModel(["アイテム1", "アイテム2", "アイテム3"])
        self.list_view.setModel(self.model)

        layout.addWidget(self.list_view)

        central_widget = QWidget()
        central_widget.setLayout(layout)
        self.setCentralWidget(central_widget)

app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())

この例では、QStringListModelを使用してデータモデルを作成し、QListViewにバインドしています。

第13章: カスタムウィジェットの作成

PySideでは、独自のウィジェットを作成することもできます。以下は、カスタムウィジェットを作成する例です:

import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel
from PySide6.QtGui import QPainter, QColor

class ColorWidget(QWidget):
    def __init__(self, color, parent=None):
        super().__init__(parent)
        self.color = QColor(color)

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.fillRect(self.rect(), self.color)

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("カスタムウィジェットの例")

        layout = QVBoxLayout()

        red_widget = ColorWidget("red")
        green_widget = ColorWidget("green")
        blue_widget = ColorWidget("blue")

        layout.addWidget(red_widget)
        layout.addWidget(green_widget)
        layout.addWidget(blue_widget)

        central_widget = QWidget()
        central_widget.setLayout(layout)
        self.setCentralWidget(central_widget)

app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())

このコードでは、ColorWidgetクラスを作成し、指定された色で塗りつぶされたウィジェットを表示しています。

第14章: スタイルシートの使用

PySideでは、スタイルシートを使用してウィジェットの外観をカスタマイズできます。以下は、スタイルシートを使用した例です:

import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("スタイルシートの例")

        layout = QVBoxLayout()

        button1 = QPushButton("ボタン1")
        button2 = QPushButton("ボタン2")
        button3 = QPushButton("ボタン3")

        layout.addWidget(button1)
        layout.addWidget(button2)
        layout.addWidget(button3)

        central_widget = QWidget()
        central_widget.setLayout(layout)
        self.setCentralWidget(central_widget)

        self.setStyleSheet("""
            QPushButton {
                background-color: #3498db;
                color: white;
                border-radius: 5px;
                padding: 10px;
            }
            QPushButton:hover {
                background-color: #2980b9;
            }
        """)

app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())

この例では、QPushButtonの背景色や文字色をスタイルシートでカスタマイズしています。

第15章: プロジェクトの構造とデプロイ

最後に、PySideプロジェクトの構造とデプロイ方法について説明します。プロジェクトを整理するために、以下のようなディレクトリ構造を推奨します:

my_pyside_app/
│
├── main.py
├── widgets/
│   ├── __init__.py
│   └── custom_widget.py
├── resources/
│   ├── images/
│   └── styles/
└── README.md

デプロイ

アプリケーションをデプロイするには、PyInstallerを使用して実行可能ファイルを作成できます。以下のコマンドでインストールできます:

pip install pyinstaller

次に、以下のコマンドで実行可能ファイルを作成します:

pyinstaller --onefile main.py

これにより、distフォルダに実行可能ファイルが生成され、他のユーザーがPython環境を持っていなくてもアプリケーションを実行できるようになります。


以上で、PySideを使用したPythonのGUI開発に関する基本的な15章の解説を終わります。このガイドが、PySideを使ったアプリケーション開発の第一歩となることを願っています。興味を持たれた方は、さらに公式ドキュメントや他のリソースを活用して、より高度な機能やカスタマイズに挑戦してみてください。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2