【PyQt5 GUI実践】気象データ可視化アプリを作ろう!(1) ウィンドウとレイアウト設計 🎨

「コマンドラインのスクリプトも良いけど、やっぱりウィンドウやボタンのある『アプリ』が作りたい!」
「Pythonで本格的なデスクトップアプリケーション開発って、どうやって始めるの?」
「地図をクリックして場所を選ぶみたいな、リッチなUIを作ってみたい!」

こんにちは! Pythonプログラミング探検隊、隊長のPythonistaです! これまで私たちは、データ分析や自動化など、主にコンソール(黒い画面)上で動作する強力なスクリプトを作成してきました。今回から始まる新シリーズでは、ついにその集大成として、誰もが使える**本格的なデスクトップGUIアプリケーション**の開発に挑戦します!

今回のプロジェクトで作成するのは、「地図上で場所を選び、カレンダーで期間を指定して、過去の気象データをグラフで可視化する」という、非常に実用的なアプリケーションです。これを実現するために、PythonのGUIフレームワークの中でも特に高機能でプロフェッショナルな現場でも使われるPyQt5を利用します。

シリーズ第1回となる今回は、まずアプリケーションの「骨格」となる**ウィンドウを作成し、必要な部品(ウィジェット)を配置して、レイアウトを整える**ところまでをマスターします。さあ、あなたのPythonスキルを、本格的なアプリ開発へと昇華させましょう!


1. プロジェクトの準備:PyQt5と必要なライブラリ

今回の主役はPyQt5です。これは、Qtという非常に有名で強力なクロスプラットフォームGUIフレームワークを、Pythonから利用できるようにしたものです。Tkinterよりも複雑ですが、その分はるかに高機能で美しいアプリケーションを作成できます。

1.1. ライブラリのインストール

まずはpipで必要なライブラリをインストールしましょう。今回はWebコンテンツを表示するためのPyQtWebEngineも一緒にインストールします。

pip install PyQt5 PyQtWebEngine

(今後の回で必要になる、pandas, matplotlib, geopyなどもインストールしておきましょう。)

1.2. アプリの設計図

今回作成するアプリの完成形をイメージしましょう。


ウィンドウ全体を左右に分割し、

  • 左側(コントロールパネル): 地点情報、期間選択カレンダー、実行ボタンなどを配置。
  • 右側(メインビュー): クリックできるインタラクティブな地図を配置。

このようなレイアウトを目指して、ウィンドウの骨格から作っていきます。


2. ステップ1:最初のウィンドウとGUIの骨格作り

まずは、PyQt5でアプリケーションの最も基本的な骨格を作成します。

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget

# アプリケーションのメインウィンドウを定義するクラス
class WeatherApp(QMainWindow):
    def __init__(self):
        # 親クラスのコンストラクタを呼び出す
        super().__init__()
        
        # ウィンドウの基本的な設定
        self.setWindowTitle("気象データ可視化ツール")
        self.setGeometry(100, 100, 1000, 800) # (x, y, width, height)
        
        # ここにウィジェットを作成し、配置していく(後ほど実装)
        self.initUI()

    def initUI(self):
        # UIの初期化を行うメソッド(今はまだ空)
        pass

# アプリケーションを実行するための定型句
if __name__ == '__main__':
    app = QApplication(sys.argv) # QApplicationオブジェクトを作成
    ex = WeatherApp()            # WeatherAppのインスタンスを作成
    ex.show()                    # ウィンドウを表示
    sys.exit(app.exec_())        # イベントループを開始

このコードを実行すると、まだ中身は空ですが、指定したタイトルとサイズのウィンドウが表示されるはずです。if __name__ == '__main__':ブロックが、このスクリプトを直接実行したときにアプリケーションを起動するためのお決まりの書き方です。


3. ステップ2:レイアウト管理でウィジェットを美しく配置

Tkinterの.grid()と同様に、PyQt5にもウィジェットを整然と並べるための**レイアウトマネージャ**があります。今回は、水平・垂直にウィジェットを並べるQHBoxLayoutQVBoxLayoutを使います。

  • QHBoxLayout (Horizontal Box Layout): ウィジェットを水平(横)方向に並べます。
  • QVBoxLayout (Vertical Box Layout): ウィジェットを垂直(縦)方向に並べます。

これらのレイアウトを入れ子にすることで、複雑な配置も実現できます。今回は、大きなQHBoxLayoutで左右に分割し、左側にはQVBoxLayoutを配置します。

# WeatherAppクラスのinitUIメソッドの中身を書いていく
# from PyQt5.QtWidgets import QVBoxLayout, QHBoxLayout, QWidget

def initUI(self):
    # 全てのウィジェットを乗せるための中心となるウィジェット
    central_widget = QWidget()
    self.setCentralWidget(central_widget)
    
    # 全体のレイアウト (水平方向)
    main_layout = QHBoxLayout(central_widget)

    # --- 左側のコントロールパネル ---
    # ウィジェットを垂直に並べるためのレイアウト
    controls_layout = QVBoxLayout()
    
    # (後でここにラベルやボタンを追加していく)
    
    # --- 右側のメインビュー (今は空) ---
    # (後でここに地図を追加する)
    
    # 全体レイアウトに、左のパネルと右のビューを追加
    main_layout.addLayout(controls_layout, 1) # 伸縮の比率を1に
    # main_layout.addWidget(self.map_view, 3) # 右側は後で追加。伸縮比率3

4. ステップ3:コントロールパネルの部品(ウィジェット)を作成・配置

それでは、設計図に従って、左側のコントロールパネルに必要なウィジェットを作成し、controls_layoutに追加していきましょう。

# initUIメソッドの中身をさらに充実させる
# from PyQt5.QtWidgets import QLabel, QDateEdit, QPushButton, QStatusBar
# from PyQt5.QtCore import QDate

    # ... (レイアウトの準備は同じ) ...

    # --- ウィジェットの作成 ---
    # 地点選択ラベル
    self.location_label = QLabel(f"選択地点: (未選択)\n(Lat: ---, Lon: ---)")
    controls_layout.addWidget(self.location_label)

    # 期間選択 (開始日)
    controls_layout.addWidget(QLabel("開始日:"))
    self.start_date_edit = QDateEdit(calendarPopup=True)
    self.start_date_edit.setDate(QDate.currentDate().addYears(-1)) # デフォルトを1年前に
    controls_layout.addWidget(self.start_date_edit)

    # 期間選択 (終了日)
    controls_layout.addWidget(QLabel("終了日:"))
    self.end_date_edit = QDateEdit(calendarPopup=True)
    self.end_date_edit.setDate(QDate.currentDate()) # デフォルトを今日に
    controls_layout.addWidget(self.end_date_edit)
    
    # 実行ボタン
    self.fetch_button = QPushButton("データ取得 & グラフ表示")
    # self.fetch_button.clicked.connect(self.run_analysis) # ボタンの動作は次回以降
    controls_layout.addWidget(self.fetch_button)

    # 空白を追加してウィジェットを上に寄せる
    controls_layout.addStretch()
    
    # --- 右側の地図ビュー (今回はプレースホルダ) ---
    map_placeholder = QLabel("ここに地図が表示されます")
    map_placeholder.setStyleSheet("background-color: lightgrey; border: 1px solid black;")
    
    # 全体レイアウトに追加
    main_layout.addLayout(controls_layout, 1)
    main_layout.addWidget(map_placeholder, 3) # 左右の幅の比率を 1:3 に

    # ステータスバーの追加
    self.setStatusBar(QStatusBar(self))
    self.statusBar().showMessage("準備完了。地図をクリックして地点を選択してください。")

ここまでで、アプリケーションの「見た目」の骨格が完成しました!まだボタンを押しても何も起きませんが、カレンダーをクリックして日付を選んだり、ウィンドウサイズを変えてもレイアウトが崩れなかったりすることを確認できます。


まとめと次回予告

今回は、本格的なGUIアプリケーション開発への第一歩として、PyQt5を使ったウィンドウとレイアウトの基本を学びました。

  • PyQt5アプリケーションの基本的な骨格 (QApplication, QMainWindow)。
  • ウィジェットを水平・垂直に並べるためのレイアウトマネージャ (QHBoxLayout, QVBoxLayout)。
  • 様々な部品 (QLabel, QDateEdit, QPushButton) の作成と配置。
  • アプリケーション全体をクラスとして設計する、オブジェクト指向的なアプローチ。

GUIアプリケーションの開発は、このようにまず「見た目」の骨格を作り、そこに少しずつ「魂」(機能ロジック)を吹き込んでいく、という流れで進めるのが一般的です。

さて、レイアウトは完成しましたが、肝心の地図が表示されていませんし、クリックもできません。次回、シリーズ第2回では、いよいよこのアプリの最も面白くて核心的な部分、右側のエリアにインタラクティブな地図を表示し、クリックした場所の緯度経度をPython側で受け取るという、JavaScriptとPythonを連携させるブリッジ技術に挑戦します!お楽しみに!

その他の投稿はこちら

コメント

このブログの人気の投稿

タイトルまとめ

これで迷わない!WindowsでPython環境構築する一番やさしい方法 #0

【Python標準ライブラリ完結!】11の冒険をありがとう!君のPython力が飛躍する「次の一歩」とは? 🚀