requestsとTkinterで作る偉人名言表示アプリケーションプロジェクト

DEMO

このプロジェクトでは、Web APIから取得した偉人や著名人のランダムな名言を表示するGUIデスクトップアプリケーションを作成します。シンプルで使いやすいインターフェースを持ち、ボタンをクリックするだけで新しい名言が表示されます。アプリケーションには適切なエラーハンドリングが実装されており、ネットワークエラーが発生した場合も安全に動作します。完成したアプリケーションは、HTTP通信とGUI開発の基礎技術を実践的に学習できる教材として最適です。(最終的なウィンドウのスクショを貼り付けます)

目次

プロジェクト概要

前提条件

  • Pythonプログラミングの基本的な知識(変数、関数、クラスの概念)
  • VSCodeエディタの基本操作ができること
  • ターミナル(コマンドライン)の基本的な使用経験
  • Gitとバージョン管理の基礎知識
  • インターネット接続環境

開発環境

  • Python 3.7以上
  • VSCode(Visual Studio Code)
  • Git(バージョン管理システム)
  • GitHubアカウント
  • requests(HTTP通信ライブラリ)
  • tkinter(GUI開発ライブラリ)

プロジェクト内容

このプロジェクトでは、Pythonのrequestsライブラリとtkinterライブラリを組み合わせて、Web APIから偉人や著名人の名言データを取得してGUIで表示するデスクトップアプリケーションを構築します。初心者でも段階的に学習できるよう、環境設定からAPI連携、GUI実装まで4つのステップに分けて進めていきます。

プロジェクトの核となるのは、HTTP通信によるリアルタイムなデータ取得技術です。requestsライブラリを使用してAdvice Slip APIと連携し、ランダムな人生のアドバイスを取得します。取得したJSONデータを適切に処理し、tkinterで作成したGUIに表示することで、実用的なアプリケーションを開発します。

適切なエラーハンドリングの実装により、ネットワークエラーやAPI障害が発生した場合でも安全に動作するシステムを作成します。最終的に、完成したプロジェクトをGitHubにアップロードし、ポートフォリオとして活用できる形にします。

実装内容

  • HTTP通信の基本設定とAPI接続テスト機能
  • 仮想環境の構築と依存関係管理(requirements.txt)
  • JSON形式データの取得と処理ロジック
  • tkinterを使用したGUIウィンドウの作成
  • ボタン、ラベル、フレームの配置とレイアウト設計
  • イベント処理とデータ更新機能
  • エラーハンドリングとユーザー通知システム
  • GitHubでのバージョン管理とポートフォリオ公開

得られるスキル

  • requests(HTTP通信、Web API連携、JSONデータ処理)
  • tkinter(GUI開発、ウィジェット配置、イベント処理)
  • HTTP通信の基礎(GETリクエスト、レスポンス処理)
  • エラーハンドリング(例外処理、ユーザー体験向上)

得られる経験

  • Web APIとの連携開発経験
  • GUIアプリケーションの設計と実装経験
  • ユーザーインターフェース設計の実践経験
  • GitHubでのプロジェクト管理経験

得られる成果物

  • 完全に動作するGUIデスクトップアプリケーション
  • GitHubでのポートフォリオとして活用可能なプロジェクト
  • 完全なPythonソースコード

このプロジェクトから応用できること

  • 天気情報表示アプリをrequestsライブラリで天気APIと連携して開発
  • ニュース取得アプリをtkinterでリスト表示機能を追加して構築
  • 株価情報表示ツールをJSON処理技術を活用して作成
  • 翻訳アプリをHTTP通信技術で翻訳APIと連携して開発
  • API連携ツールの受託開発でクラウドワークス案件として活用

Step1:開発環境の準備とプロジェクト構造の作成

このステップでは、名言表示アプリケーションプロジェクトを始めるための開発環境を整備し、必要なファイル構造を作成していきます。プログラミングを始める前の準備段階として、とても重要な作業になります。

※Step1の内容がわからない際は、下記記事にGitHubとVSCodeの連携について詳細を記載しているためご参照ください。

GitHubリポジトリの作成

まず最初に、プロジェクト専用のGitHubリポジトリを作成しましょう。

  1. GitHubの公式サイトにアクセスし、自分のアカウントでログインします
  2. 画面右上の「+」アイコンをクリックし、ドロップダウンメニューから「New repository」を選択します
  3. 新しいリポジトリの作成ページで、以下の情報を入力します

リポジトリの設定

  • Repository namewisdom_quotes_app」と入力
  • Description世界の偉人・著名人の名言をランダム表示するGUIアプリケーション」と入力
  • VisibilityPublic」を選択(ポートフォリオとして公開するため)
  • Initialize this repository with
    • Add a README file」にチェックを入れる
    • Add .gitignore」で「Python」を選択
    • Choose a license」は「None」のままにする
  1. Create repository」ボタンをクリックしてリポジトリを作成します

プロジェクトフォルダの作成

次に、プロジェクトを管理するための親フォルダを作成しましょう。

Windows・macOS共通

  1. デスクトップや任意の場所に新しいフォルダを作成します
  2. フォルダ名は任意ですが、ここでは例として「PythonPortfolio」に設定します

この親フォルダが、今後のプロジェクト全体を管理するルートディレクトリとなります。複数のプロジェクトを整理して管理するために作成しておくと便利です。

VSCodeでプロジェクトを開く

作成したGitHubリポジトリをローカルにクローンして開きましょう。

  1. VSCodeを起動します
  2. 左側のアクティビティバーからソース管理アイコン(分岐のようなアイコン)をクリックします
  3. リポジトリの複製」ボタンをクリックします
  4. GitHubから複製」を選択します
  5. 先ほど作成した「wisdom_quotes_app」リポジトリを選択します
  6. リポジトリ宛先として先ほど作成した親フォルダを選択します
  7. クローンしたリポジトリを開きますか」というウィンドウが表示されたら「開く」をクリックします

VSCodeの左側にエクスプローラーパネルが表示され、現在のプロジェクトフォルダの中身が確認できるようになります。

仮想環境の作成とアクティベート

Python開発において仮想環境は非常に重要です。仮想環境とは、プロジェクトごとに独立したPython実行環境を作成する仕組みのことです。これにより、プロジェクト間でのライブラリの競合を防ぎ、クリーンな開発環境を維持できます。

詳しくは下記記事をご参照ください。

Windows環境での仮想環境作成

  1. VSCodeの上部メニューから「ターミナル」→「新しいターミナル」を選択
  2. 以下のコマンドで仮想環境を作成します
python -m venv myenv
  1. 仮想環境をアクティベートします
myenv\Scripts\activate

macOS環境での仮想環境作成

  1. VSCodeの上部メニューから「ターミナル」→「新しいターミナル」を選択
  2. 以下のコマンドで仮想環境を作成します
python3 -m venv myenv
  1. 仮想環境をアクティベートします
source myenv/bin/activate

重要なポイント

  • 仮想環境名は「myenv」として作成
  • ターミナルの行頭に「(myenv)」と表示されることを確認
  • この表示があることで、仮想環境が正常にアクティベートされていることがわかります

プロジェクトファイル構造の作成

次に、今回の名言表示アプリケーションプロジェクトに必要なファイルを作成していきます。VSCodeのエクスプローラーパネルを使用してファイルを作成しましょう。

メインアプリケーションファイルの作成

  1. VSCodeの左側エクスプローラーパネルで、プロジェクトルートフォルダ(wisdom_quotes_app)をクリックして選択
  2. 新しいファイル」アイコン(ファイルの絵とプラスのマークがあるアイコン)をクリック
  3. ファイル名を「quote_display_app.py」として作成

この「quote_display_app.py」ファイルが、今回の名言表示機能を実装するメインプログラムとなります。.py拡張子Pythonスクリプトファイルであることを示しており、実行可能なプログラムコードを記述するために使用します。

依存関係管理ファイルの作成

  1. プロジェクトのルートフォルダ(wisdom_quotes_app)をクリックして選択
  2. 新しいファイル」アイコンをクリック
  3. ファイル名を「requirements.txt」として作成

requirements.txtファイルは、Pythonプロジェクトで使用する外部ライブラリとそのバージョンを記録するための重要なファイルです。これにより、他の開発者や本番環境でも同じライブラリ環境を再現できます。

requirements.txtの内容設定

作成した「requirements.txt」ファイルをVSCodeで開き、以下の内容を記述してください。

requests==2.32.4

今回のプロジェクトでは、requestsというライブラリを使用します。

  • requests HTTP通信を簡単に行うためのPythonライブラリです。Web上の名言APIから名言データを取得する際に使用します。GET、POST、PUT、DELETEなどのHTTPメソッドを簡潔なコードで実行でき、JSON形式のデータ処理も効率的に行えます

プロジェクト構造の確認

この時点で、VSCodeのエクスプローラーパネルには以下のような構造が表示されているはずです。

wisdom_quotes_app/
├── myenv/                      # 仮想環境フォルダ
├── quote_display_app.py        # メインアプリケーションファイル
├── requirements.txt            # 依存関係管理ファイル
├── README.md                   # プロジェクト説明書(GitHub作成時に自動生成)
└── .gitignore                  # Git除外設定ファイル(GitHub作成時に自動生成)

このシンプルな構造が、今回の名言表示アプリケーションプロジェクトの基盤となります。GitHubで作成したリポジトリをクローンしたため、README.md.gitignoreファイルが最初から含まれています。

仮想環境が正常にアクティベートされていることを再度確認し(ターミナルに「(myenv)」が表示されている状態)、次のステップに進む準備を整えましょう。

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

仮想環境がアクティベートされている状態で、VSCodeのターミナルから以下のコマンドを実行します。

pip install -r requirements.txt

このコマンドにより、requirements.txtに記載されたrequestsライブラリがインストールされます。インストール処理には数十秒程度かかる場合がありますので、しばらくお待ちください。

インストールが完了すると、ターミナルに「Successfully installed requests-2.32.4」のようなメッセージが表示され、プロジェクトの環境準備が完了します。

これで開発環境の準備とプロジェクト構造の作成が完了しました。次のステップでは、名言APIからデータを取得する機能を実装していきます。


Step2:名言APIの動作確認とデータ取得機能の実装

このステップでは、Web上の名言APIから実際にデータを取得する機能を実装します。HTTP通信の基本的な仕組みを理解し、JSON形式のデータ処理方法を学んでいきます。

QuoteAPIManagerクラスの作成

まず、名言データの取得機能をまとめて管理するクラスを作成します。このクラスの中に、今後必要な機能をすべてdef文(関数)として実装していきます。

quote_display_app.py」ファイルを開き、以下のコードを記述してください。

# 必要なライブラリをインポート
import requests  # HTTP通信を行うためのライブラリ
import json      # JSONデータの処理用ライブラリ

class QuoteAPIManager:
    """名言APIとの通信を管理するクラス"""
    
    def __init__(self):
        """クラスの初期化メソッド"""
        # 使用する名言APIのベースURL
        self.api_url = "https://api.adviceslip.com/advice"
        # リクエストのタイムアウト時間(秒)
        self.timeout = 10
        # HTTPヘッダー情報
        self.headers = {
            'User-Agent': 'WisdomQuotesApp/1.0'  # アプリの識別情報
        }

__init__メソッドはクラスの初期化を行う特別な関数です。ここでAPIのURL設定やタイムアウト時間、HTTPヘッダー情報を定義しています。

API接続テスト機能の実装

次に、クラス内にtest_api_connectionメソッドを実装します。

    def test_api_connection(self):
        """APIとの接続をテストするメソッド"""
        try:
            # APIに対してGETリクエストを送信
            response = requests.get(
                self.api_url,           # リクエスト先のURL
                headers=self.headers,   # HTTPヘッダー情報
                timeout=self.timeout    # タイムアウト時間
            )
            
            # HTTPステータスコードが200番台かチェック
            response.raise_for_status()
            
            # レスポンスが正常に取得できた場合
            print("✓ API接続テスト成功")
            print(f"ステータスコード: {response.status_code}")                    # HTTPステータスコードを表示
            print(f"レスポンス時間: {response.elapsed.total_seconds():.2f}秒")     # 応答時間を表示
            
            return True  # 接続成功を返す
            
        except requests.exceptions.Timeout:
            # タイムアウトエラーの処理
            print("✗ API接続エラー: タイムアウトが発生しました")
            return False  # 接続失敗を返す
            
        except requests.exceptions.ConnectionError:
            # 接続エラーの処理
            print("✗ API接続エラー: インターネット接続を確認してください")
            return False  # 接続失敗を返す
            
        except requests.exceptions.RequestException as e:
            # その他のHTTPエラーの処理
            print(f"✗ API接続エラー: {str(e)}")
            return False  # 接続失敗を返す

このメソッドはクラス内で定義されているため、selfキーワードを使用してクラスの属性にアクセスできます。requests.get()関数を使用してHTTP GETリクエストを送信し、様々なエラーパターンに対応しています。

HTTP通信について

HTTP(HyperText Transfer Protocol)は、Webブラウザとサーバー間でデータをやり取りするための通信プロトコルです。GETリクエストは、サーバーからデータを取得する際に使用される最も基本的なHTTPメソッドです。

名言データ取得機能の実装

QuoteAPIManagerクラス内に、実際に名言データを取得するメソッドを追加します。

    def fetch_random_quote(self):
        """ランダムな名言を取得するメソッド"""
        try:
            # APIに対してGETリクエストを送信
            response = requests.get(
                self.api_url,           # リクエスト先のURL
                headers=self.headers,   # HTTPヘッダー情報
                timeout=self.timeout    # タイムアウト時間
            )
            
            # HTTPステータスコードをチェック
            response.raise_for_status()
            
            # JSON形式のレスポンスを辞書型に変換
            quote_data = response.json()
            
            # Advice Slip APIの形式に合わせてデータを整理
            slip_data = quote_data.get('slip', {})                             # 'slip'キーのデータを取得
            quote_text = slip_data.get('advice', '名言を取得できませんでした')   # 名言テキストを取得
            
            # 取得したデータを整理して辞書形式で返す
            formatted_quote = {
                'content': quote_text,                # 名言の内容
                'id': slip_data.get('id', 0),         # 名言のID番号
                'length': len(quote_text),           # 名言の文字数
                'category': 'life wisdom'             # 名言のカテゴリ
            }
            
            return formatted_quote  # 整理されたデータを返す
            
        except requests.exceptions.RequestException as e:
            # エラーが発生した場合のデフォルトデータを返す
            error_quote = {
                'content': 'エラーが発生しました。しばらくしてからもう一度お試しください。',
                'id': 0,                    # エラー時のID
                'length': 0,                # エラー時の文字数
                'category': 'error'         # エラーカテゴリ
            }
            print(f"名言取得エラー: {str(e)}")  # エラー内容をコンソールに出力
            return error_quote  # エラー用のデータを返す

response.json()メソッドは、サーバーから受信したJSON形式のデータをPythonの辞書型オブジェクトに自動変換する便利な機能です。get()メソッドを使用することで、辞書にキーが存在しない場合でもエラーを回避できます。

JSON形式について

JSON(JavaScript Object Notation)は、データ交換のための軽量なテキスト形式です。キーと値のペアで構成され、PythonやJavaScript、多くのプログラミング言語で簡単に処理できます。Web APIの標準的なデータ形式として広く使用されています。

データ表示機能の実装

取得した名言データを見やすく表示するメソッドをクラス内に追加します。

    def display_quote_info(self, quote_data):
        """名言データを整形して表示するメソッド"""
        # 見やすい区切り線を表示
        print("\n" + "="*60)
        print("💡 取得した名言情報")
        print("="*60)
        
        # 名言の内容を表示
        print(f"💬 名言: {quote_data['content']}")    # 名言のテキスト
        print(f"🔢 ID番号: {quote_data['id']}")           # 名言のID
        print(f"📏 文字数: {quote_data['length']}文字")    # 文字数
        print(f"📂 カテゴリ: {quote_data['category']}")    # カテゴリ情報
        
        # 区切り線で終了
        print("="*60 + "\n")

len()関数は、文字列や配列の長さを取得する際に使用します。ここでは名言の文字数を計算して表示しています。

複数名言取得機能の実装

一度に複数の名言を取得できるメソッドをクラス内に追加します。

    def fetch_multiple_quotes(self, count=3):
        """指定した数の名言を取得するメソッド"""
        quotes_list = []          # 名言を格納するリスト
        successful_requests = 0   # 成功したリクエスト数のカウンター
        
        # 取得開始のメッセージを表示
        print(f"🔄 {count}個の名言を取得中...")
        
        # 指定された回数だけ名言を取得
        for i in range(count):
            # 進捗状況を表示
            print(f"取得中... ({i+1}/{count})")
            
            # 1つずつ名言を取得
            quote = self.fetch_random_quote()
            
            # エラーでない場合はリストに追加
            if quote['category'] != 'error':
                quotes_list.append(quote)      # 正常な名言をリストに追加
                successful_requests += 1        # 成功カウンターを増加
            
            # API負荷軽減のため少し待機
            import time
            time.sleep(0.5)  # 0.5秒待機
        
        # 取得完了のメッセージを表示
        print(f"✓ {successful_requests}個の名言を正常に取得しました\n")
        return quotes_list  # 取得した名言のリストを返す

time.sleep()関数を使用してAPIリクエスト間に間隔を設けることで、サーバーへの負荷を軽減しています。これはレート制限への配慮として重要な実装です。

統計情報計算機能の実装

取得した名言データの統計情報を計算するメソッドをクラス内に追加します。

    def calculate_quote_stats(self, quotes_list):
        """名言リストの統計情報を計算するメソッド"""
        # 名言リストが空の場合の処理
        if not quotes_list:
            return None  # 統計情報なしを返す
        
        # 文字数のリストを作成(リスト内包表記を使用)
        lengths = [quote['length'] for quote in quotes_list]
        
        # 統計情報を計算して辞書形式で格納
        stats = {
            'total_count': len(quotes_list),                    # 総名言数
            'avg_length': round(sum(lengths) / len(lengths), 1), # 平均文字数(小数点1桁)
            'max_length': max(lengths),                         # 最長文字数
            'min_length': min(lengths),                         # 最短文字数
            'total_chars': sum(lengths)                         # 総文字数
        }
        
        return stats  # 計算した統計情報を返す
    
    def display_stats(self, stats):
        """統計情報を表示するメソッド"""
        # 統計情報がない場合の処理
        if not stats:
            print("統計情報がありません")
            return
        
        # 統計情報を見やすく表示
        print("📊 名言統計情報")
        print("-" * 30)
        print(f"総名言数: {stats['total_count']}個")      # 総数
        print(f"平均文字数: {stats['avg_length']}文字")         # 平均
        print(f"最長文字数: {stats['max_length']}文字")         # 最大値
        print(f"最短文字数: {stats['min_length']}文字")         # 最小値
        print(f"総文字数: {stats['total_chars']}文字")          # 合計
        print("-" * 30 + "\n")

リスト内包表記を使用してデータの抽出と処理を効率的に行っています。round()関数は小数点以下の桁数を調整するために使用します。

メイン実行部分の実装

これまでに作成した機能をテストするためのメイン実行部分を追加します。

def main():
    """メインの実行関数"""
    # アプリケーション開始のメッセージ
    print("🌟 名言表示アプリケーション - API接続テスト")
    print("="*50)
    
    # QuoteAPIManagerのインスタンスを作成
    quote_manager = QuoteAPIManager()
    
    # API接続テストを実行
    print("1. API接続テストを開始...")
    connection_success = quote_manager.test_api_connection()  # 接続テストを実行
    
    # 接続に失敗した場合はプログラムを終了
    if not connection_success:
        print("API接続に失敗しました。プログラムを終了します。")
        return  # main関数を終了
    
    # 単一名言の取得テスト
    print("\n2. 単一名言の取得テスト...")
    single_quote = quote_manager.fetch_random_quote()      # 1つの名言を取得
    quote_manager.display_quote_info(single_quote)        # 取得した名言を表示
    
    # 複数名言の取得テスト
    print("3. 複数名言の取得テスト...")
    multiple_quotes = quote_manager.fetch_multiple_quotes(3) # 3つの名言を取得
    
    # 取得した複数の名言を順番に表示
    for idx, quote in enumerate(multiple_quotes, 1):         # インデックス付きでループ
        print(f"\n--- 名言 {idx} ---")
        quote_manager.display_quote_info(quote)           # 各名言を表示
    
    # 統計情報を計算して表示
    stats = quote_manager.calculate_quote_stats(multiple_quotes)  # 統計を計算
    quote_manager.display_stats(stats)                             # 統計情報を表示

# プログラムのエントリーポイント
if __name__ == "__main__":
    main()  # main関数を実行

if name == “main”は、このファイルが直接実行された場合にのみmain関数を呼び出すPythonの構文です。enumerate()関数は、リストの要素とそのインデックス番号を同時に取得する際に使用します。

動作テスト実行

VSCodeのターミナルでプログラムを実行してテストします。

python quote_display_app.py

出力:ターミナルの出力

# Step2
🌟 アドバイス表示アプリケーション - API接続テスト
==================================================
1. API接続テストを開始...
✓ API接続テスト成功
ステータスコード: 200
レスポンス時間: 0.98秒

2. 単一アドバイスの取得テスト...

============================================================
💡 取得したアドバイス情報
============================================================
💬 アドバイス: If you get stuck, try doing the opposite of what the solution requires.
🔢 ID番号: 57
📏 文字数: 71文字
📂 カテゴリ: life advice
============================================================

3. 複数アドバイスの取得テスト...
🔄 3個のアドバイスを取得中...
取得中... (1/3)
取得中... (2/3)
取得中... (3/3)
✓ 3個のアドバイスを正常に取得しました


--- アドバイス 1 ---

============================================================
💡 取得したアドバイス情報
============================================================
💬 アドバイス: Never regret. If it's good, it's wonderful. If it's bad, it's experience.
🔢 ID番号: 179
📏 文字数: 73文字
📂 カテゴリ: life advice
============================================================


--- アドバイス 2 ---

============================================================
💡 取得したアドバイス情報
============================================================
💬 アドバイス: You're not as fat as you think you are.
🔢 ID番号: 111
📏 文字数: 39文字
📂 カテゴリ: life advice
============================================================


--- アドバイス 3 ---

============================================================
💡 取得したアドバイス情報
============================================================
💬 アドバイス: Never write in an email to someone, something which you wouldn't say to that person's face.
🔢 ID番号: 86
📏 文字数: 91文字
📂 カテゴリ: life advice
============================================================

📊 アドバイス統計情報
------------------------------
総アドバイス数: 3個
平均文字数: 67.7文字
最長文字数: 91文字
最短文字数: 39文字
総文字数: 203文字
------------------------------

Step3:GUIインターフェースの構築

このステップでは、tkinterを使用してグラフィカルユーザーインターフェース(GUI)を構築します。ユーザーが直感的に操作できるデスクトップアプリケーションの基盤を作成していきます。

tkinterライブラリのインポート

quote_display_app.py」ファイルの先頭部分に、GUIライブラリのインポート文を追加します。

# 必要なライブラリをインポート
import requests                # HTTP通信を行うためのライブラリ
import json                    # JSONデータの処理用ライブラリ
import tkinter as tk           # GUIアプリケーション作成用ライブラリ
from tkinter import messagebox # ダイアログボックス表示用モジュール
import time                    # 時間処理用ライブラリ

tkinterは、Pythonに標準で付属しているGUI開発ライブラリです。ウィンドウ、ボタン、ラベルなどのウィジェットと呼ばれるGUI部品を簡単に作成できます。messageboxは、エラーメッセージや確認ダイアログを表示するためのモジュールです。

QuoteDisplayGUIクラスの作成

GUIの機能をまとめて管理する新しいクラスを作成します。既存のQuoteAPIManagerクラスの下に以下のコードを追加してください。

class QuoteDisplayGUI:
    """名言表示GUIを管理するクラス"""
    
    def __init__(self):
        """GUIクラスの初期化メソッド"""
        # APIマネージャーのインスタンスを作成
        self.api_manager = QuoteAPIManager()
        
        # メインウィンドウの作成と設定
        self.root = tk.Tk()  # tkinterのメインウィンドウを作成
        self.setup_window()  # ウィンドウの基本設定を実行
        
        # GUI要素用の変数を初期化
        self.quote_text = tk.StringVar()  # 名言表示用の文字列変数
        self.quote_text.set("「名言を取得」ボタンをクリックしてください")  # 初期メッセージを設定
        
        # ウィジェットを作成
        self.create_widgets()  # GUI部品を作成
        
        # レイアウトを設定
        self.setup_layout()    # ウィジェットの配置を設定

StringVar()は、tkinterでテキストを動的に管理するための特別な変数クラスです。この変数の値が変更されると、それに関連付けられたウィジェットの表示も自動的に更新されます。

ウィンドウ基本設定機能の実装

GUIウィンドウの基本的な外観と動作を設定するメソッドを追加します。

    def setup_window(self):
        """メインウィンドウの基本設定を行うメソッド"""
        # ウィンドウのタイトル設定
        self.root.title("人生の名言表示アプリ")
        
        # ウィンドウサイズの設定(幅x高さ)
        self.root.geometry("600x400")
        
        # ウィンドウの最小サイズを設定
        self.root.minsize(500, 300)
        
        # ウィンドウの背景色を設定(薄い青色)
        self.root.configure(bg='#f0f8ff')
        
        # ウィンドウを画面中央に配置
        self.center_window()
        
        # ウィンドウが閉じられる時の処理を設定
        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)

geometry()メソッドは、ウィンドウのサイズを「幅x高さ」の形式で指定します。configure()メソッドを使用してウィンドウの背景色を設定できます。ここでは薄い青色(#f0f8ff)を使用しています。

ウィンドウ中央配置機能の実装

ウィンドウを画面の中央に表示するためのメソッドを追加します。

    def center_window(self):
        """ウィンドウを画面中央に配置するメソッド"""
        # ウィンドウの更新を待つ
        self.root.update_idletasks()
        
        # 画面の幅と高さを取得
        screen_width = self.root.winfo_screenwidth()   # モニターの幅
        screen_height = self.root.winfo_screenheight() # モニターの高さ
        
        # ウィンドウの幅と高さを取得
        window_width = self.root.winfo_reqwidth()      # ウィンドウの幅
        window_height = self.root.winfo_reqheight()    # ウィンドウの高さ
        
        # 中央配置のための座標を計算
        x = (screen_width - window_width) // 2         # X座標(水平中央)
        y = (screen_height - window_height) // 2       # Y座標(垂直中央)
        
        # ウィンドウの位置を設定
        self.root.geometry(f"+{x}+{y}")

winfo_screenwidth()とwinfo_screenheight()は、使用しているモニターの解像度を取得するメソッドです。//演算子は整数除算を行い、小数点以下を切り捨てます。

GUIウィジェット作成機能の実装

アプリケーションで使用するボタン、ラベルなどのGUI部品を作成するメソッドを追加します。

    def create_widgets(self):
        """GUI要素(ウィジェット)を作成するメソッド"""
        # タイトルラベルの作成
        self.title_label = tk.Label(
            self.root,                     # 親ウィンドウ
            text="💡 人生の名言 💡",    # 表示テキスト
            font=("Arial", 20, "bold"),    # フォント設定(Arial、サイズ20、太字)
            bg='#f0f8ff',                  # 背景色
            fg='#2c3e50'                   # 文字色(濃い青)
        )
        
        # 名言表示用のラベルを作成
        self.quote_label = tk.Label(
            self.root,                     # 親ウィンドウ
            textvariable=self.quote_text, # 表示する文字列変数
            font=("Arial", 12),            # フォント設定
            bg='#ffffff',                  # 背景色(白)
            fg='#34495e',                  # 文字色(グレー系)
            wraplength=450,                # 自動改行する幅
            justify='center',              # テキストの中央揃え
            relief='ridge',                # 境界線のスタイル(立体的)
            bd=3,                          # 境界線の太さ
            padx=20,                       # 水平方向の内側余白
            pady=20                        # 垂直方向の内側余白
        )
        
        # 名言取得ボタンの作成
        self.get_quote_button = tk.Button(
            self.root,                     # 親ウィンドウ
            text="名言を取得",         # ボタンのテキスト
            font=("Arial", 14, "bold"),    # フォント設定
            bg='#3498db',                  # ボタンの背景色(青)
            fg='black',                    # ボタンの文字色(黒)
            activebackground='#2980b9',    # クリック時の背景色(濃い青)
            activeforeground='black',      # クリック時の文字色(黒)
            padx=30,                       # 水平方向の内側余白
            pady=12,                       # 垂直方向の内側余白
            command=self.fetch_new_quote  # クリック時に実行する関数
        )
        
        # ステータス表示用のラベル
        self.status_label = tk.Label(
            self.root,                     # 親ウィンドウ
            text="準備完了",                # 初期表示テキスト
            font=("Arial", 10),            # フォント設定
            bg='#f0f8ff',                  # 背景色
            fg='#7f8c8d'                   # 文字色(薄いグレー)
        )

wraplengthオプションは、テキストが指定した幅を超えた場合に自動的に改行する設定です。reliefbd(border)オプションは、ウィジェットの境界線のスタイルと太さを設定します。commandパラメータには、ボタンがクリックされた時に実行される関数を指定します。

レイアウト設定機能の実装

作成したウィジェットをウィンドウ内に適切に配置するメソッドを追加します。

    def setup_layout(self):
        """ウィジェットのレイアウトを設定するメソッド"""
        # タイトルラベルを上部に配置
        self.title_label.pack(pady=(20, 15))  # 上側20px、下側15pxの余白で配置
        
        # 名言表示ラベルを中央に配置
        self.quote_label.pack(
            pady=25,        # 上下25pxの余白
            padx=20,        # 左右20pxの余白
            fill='both',    # 水平・垂直方向に拡張
            expand=True     # ウィンドウサイズ変更時に拡張
        )
        
        # 名言取得ボタンを中央に配置
        self.get_quote_button.pack(pady=15)  # 上下15pxの余白で配置
        
        # ステータスラベルを下部に配置
        self.status_label.pack(
            side='bottom',  # ウィンドウの下部に配置
            pady=15         # 上下15pxの余白
        )

pack()メソッドは、ウィジェットをウィンドウに配置するためのレイアウトマネージャーです。padyとpadxは、縦方向と横方向の余白を設定します。fillexpandオプションは、ウィンドウサイズが変更された時の動作を制御します。

イベント処理機能の実装

ボタンクリック時の処理やウィンドウが閉じられる時の処理を実装します。

    def fetch_new_quote(self):
        """新しい名言を取得してGUIに表示するメソッド"""
        # ステータス更新(取得中であることを表示)
        self.status_label.config(text="名言を取得中...")
        # ボタンを無効化(連続クリックを防止)
        self.get_quote_button.config(state='disabled')
        # GUI画面を即座に更新
        self.root.update()
        
        try:
            # APIから名言を取得
            quote_data = self.api_manager.fetch_random_quote()
            
            # エラーチェック
            if quote_data['category'] == 'error':
                # エラーダイアログを表示
                messagebox.showerror("エラー", quote_data['content'])
                # ステータスをエラー表示に更新
                self.status_label.config(text="エラーが発生しました")
                return  # 処理を終了
            
            # 名言テキストを更新(引用符で囲む)
            display_text = f'"{quote_data["content"]}"'
            self.quote_text.set(display_text)  # 表示テキストを更新
            
            # ステータス更新(ID番号と文字数を表示)
            self.status_label.config(text=f"ID: {quote_data['id']} | 文字数: {quote_data['length']}")
            
        except Exception as e:
            # 予期しないエラーの処理
            messagebox.showerror("予期しないエラー", f"名言の取得に失敗しました\n{str(e)}")
            # ステータスをエラー表示に更新
            self.status_label.config(text="エラーが発生しました")
        finally:
            # ボタンを再度有効化(エラーの有無に関わらず実行)
            self.get_quote_button.config(state='normal')
    
    def on_closing(self):
        """ウィンドウが閉じられる時の処理"""
        # 終了確認ダイアログを表示
        result = messagebox.askquestion("終了確認", "アプリケーションを終了しますか?")
        # ユーザーが「はい」を選択した場合
        if result == 'yes':
            self.root.destroy()  # ウィンドウを閉じる

config()メソッドは、既存のウィジェットの設定を動的に変更する際に使用します。update()メソッドを呼び出すことで、GUI画面を即座に更新できます。messagebox.showerror()は、エラーメッセージを表示するダイアログボックスを作成します。

アプリケーション実行機能の実装

GUIアプリケーションを起動するメソッドを追加します。

    def run_application(self):
        """GUIアプリケーションを実行するメソッド"""
        # 起動メッセージをコンソールに表示
        print("🖥️  GUIアプリケーションを起動中...")
        
        # 初期接続テストを実行
        if not self.api_manager.test_api_connection():
            # 接続に失敗した場合は警告ダイアログを表示
            messagebox.showwarning(
                "接続警告", 
                "APIサーバーに接続できません。\nインターネット接続を確認してください。"
            )
        
        # メインループを開始(ここでGUIが表示される)
        self.root.mainloop()
        
        # アプリケーション終了時のメッセージ
        print("アプリケーションが終了しました")

mainloop()は、tkinterアプリケーションのメインイベントループを開始するメソッドです。このループが実行中は、ユーザーのマウスクリックやキーボード入力などのイベントを監視し、適切な処理を実行します。

メイン実行部分の更新

プログラムの最下部のメイン実行部分を更新します。前のStep2で作成したAPIテスト用の関数はコメントアウトします。

# 以前のAPIテスト用のメイン関数(Step2で使用していたもの)
# def main():
#     """メインの実行関数"""
#     print("🌟 名言表示アプリケーション - API接続テスト")
#     print("="*50)
#     
#     # QuoteAPIManagerのインスタンスを作成
#     quote_manager = QuoteAPIManager()
#     
#     # API接続テストを実行
#     print("1. API接続テストを開始...")
#     connection_success = quote_manager.test_api_connection()
#     
#     if not connection_success:
#         print("API接続に失敗しました。プログラムを終了します。")
#         return
#     
#     print("\n2. 単一名言の取得テスト...")
#     # 1つの名言を取得してテスト
#     single_quote = quote_manager.fetch_random_quote()
#     quote_manager.display_quote_info(single_quote)
#     
#     print("3. 複数名言の取得テスト...")
#     # 3つの名言を取得してテスト
#     multiple_quotes = quote_manager.fetch_multiple_quotes(3)
#     
#     # 取得した複数の名言を順番に表示
#     for idx, quote in enumerate(multiple_quotes, 1):
#         print(f"\n--- 名言 {idx} ---")
#         quote_manager.display_quote_info(quote)
#     
#     # 統計情報を計算して表示
#     stats = quote_manager.calculate_quote_stats(multiple_quotes)
#     quote_manager.display_stats(stats)

def main():
    """GUIアプリケーションを起動するメイン関数"""
    # GUIアプリケーションのインスタンスを作成
    app = QuoteDisplayGUI()
    
    # アプリケーションを実行
    app.run_application()

# プログラムのエントリーポイント
if __name__ == "__main__":
    main()  # main関数を実行してアプリケーションを開始

新しいmain関数は、GUIアプリケーションを起動するためのシンプルな構造になっています。前のStep2で作成したCUI(コマンドラインインターフェース)テスト用のコードは、今後の参考のためにコメントアウトして残しています。

動作テスト実行

VSCodeのターミナルでプログラムを実行してGUIアプリケーションを起動します。

python quote_display_app.py

出力:アプリ画面


Step4:プロジェクトをGitHubにアップロード

このステップでは、完成した名言表示アプリケーションプロジェクトをGitHubにアップロードし、ポートフォリオとして活用できる形にします。最終的なファイル整理とコードの公開を行っていきます。

.gitignoreファイルの更新

既存の.gitignoreファイルに、プロジェクト固有の除外設定を追加します。

VSCodeで「.gitignore」ファイルを開き、以下の内容を末尾に追加してください。

# Virtual environment
myenv/

# Python cache files
__pycache__/
*.pyc
*.pyo

# IDE settings
.vscode/

これらを追加する理由について説明します。

  • myenv/ 仮想環境フォルダはプロジェクト固有のため、リポジトリに含める必要がありません
  • pycache/ Pythonが自動生成するキャッシュフォルダを除外
  • **.pyc Pythonコンパイル済みファイルを除外
  • **.pyo Python最適化済みファイルを除外
  • .vscode/ VSCode固有の設定ファイルを除外

README.mdファイルの更新

リポジトリ作成時に生成されたREADME.mdファイルの内容を、プロジェクトの詳細情報に更新します。

VSCodeで「README.md」ファイルを開き、内容を以下のように全て置き換えてください。

# 人生の名言表示アプリケーション

## プロジェクト内容

Web APIから取得したランダムな人生の名言を表示するGUIデスクトップアプリケーションです。HTTP通信によるデータ取得、JSON形式でのデータ処理、tkinterを使用したグラフィカルユーザーインターフェースの実装まで一連の処理を統合し、実用的なデスクトップアプリケーションを作成しました。PythonによるWeb API連携とGUI開発技術を学習することを目的として実装しました。

## プロジェクト構成

```
wisdom_quotes_app/
├── quote_display_app.py        # メインアプリケーション
├── requirements.txt            # 依存関係管理
├── README.md                   # プロジェクト説明書
└── .gitignore                  # Git除外ファイル設定
```

## 必要要件/開発環境

- **Python 3.7以上**
- **VSCode** (開発環境)
- **Git** (バージョン管理)
- **インターネット接続** (API通信のため)

### 使用ライブラリ

- **requests** HTTP通信とWeb API連携処理
- **tkinter** GUIアプリケーション作成
- **json** JSON形式データの処理
- **time** API負荷軽減のための待機処理

## 機能

- **Web API連携** Advice Slip APIからランダムな名言を取得
- **リアルタイムデータ表示** 取得した名言をGUIで即座に表示
- **エラーハンドリング** ネットワークエラーやAPI障害への適切な対応
- **ユーザーフレンドリーなGUI** 直感的に操作できるデスクトップインターフェース
- **接続テスト機能** アプリケーション起動時のAPI接続確認
- **ステータス表示** 取得処理の進行状況と名言情報の表示
- **ウィンドウ管理** 画面中央配置と終了確認ダイアログ
- **レスポンシブデザイン** ウィンドウサイズ変更に対応した動的レイアウト

## 実行方法

### 1. リポジトリのクローン

```bash
git clone https://github.com/yourusername/wisdom_quotes_app.git
cd wisdom_quotes_app
```

### 2. 仮想環境の作成・アクティベート

**Windows**
```bash
python -m venv myenv
myenv\Scripts\activate
```

**macOS**
```bash
python3 -m venv myenv
source myenv/bin/activate
```

### 3. 依存関係のインストール

```bash
pip install -r requirements.txt
```

### 4. アプリケーションの実行

```bash
python quote_display_app.py
```

実行後、GUIウィンドウが起動し、「名言を取得」ボタンをクリックすることで新しい名言が表示されます。

## 使用API

- **Advice Slip API** (https://api.adviceslip.com/)
  - 無料で利用可能な名言提供API
  - JSON形式でランダムな名言を返却
  - レート制限あり(適切な間隔での利用を推奨)

## 開発者

YuYu(自分の名前に置き換える)

プロジェクトのコミット・プッシュ

プロジェクトの全ての変更をGitHubに反映させましょう。

変更のステージングとコミット

  1. VSCodeの左側のアクティビティバーからソース管理アイコンをクリックします
  2. 変更内容セクションで、すべての変更ファイルを確認します
  3. 各ファイルの横にある「+」アイコンをクリックしてステージングします
  4. コミットメッセージ入力欄に「Add wisdom quotes GUI application with API integration」と入力します
  5. コミット」ボタンをクリックします

GitHubへのプッシュ

  1. コミット完了後、「変更の同期」または「プッシュ」ボタンをクリックします
  2. 初回の場合、GitHub認証が求められる場合があります
  3. 認証完了後、ローカルの変更がGitHubリポジトリに反映されます

GitHubでの確認

プロジェクトが正常にアップロードされたか確認しましょう。

  1. ブラウザでGitHubリポジトリページを開きます
  2. 以下のファイルが正しくアップロードされていることを確認します
  • quote_display_app.py (メインアプリケーションファイル)
  • requirements.txt (依存関係管理ファイル)
  • README.md (更新されたプロジェクト説明書)
  • .gitignore (更新された除外設定ファイル)
  1. README.mdが適切に表示され、プロジェクトの説明が読みやすく表示されていることを確認します
  2. ファイル一覧にmyenv/フォルダやpycache/フォルダが含まれていないことを確認します(.gitignoreで除外されているため)

これで実用的な名言表示アプリケーションが完成し、GitHubでのポートフォリオ公開も完了しました。作成したプロジェクトは、Web API連携とGUI開発の技術力を示す実績として、就職活動や案件獲得時に活用できる価値のあるアプリケーションとなっています。

まとめ

このプロジェクトを通じて、PythonによるWeb API連携とGUI開発の基礎から実践的な応用まで幅広く学習することができました。

得られたスキル

  • requests – HTTP通信、Web API連携、JSONデータ処理
  • tkinter – GUI開発、ウィジェット配置、イベント処理
  • HTTP通信の基礎 – GETリクエスト、レスポンス処理
  • エラーハンドリング – 例外処理、ユーザー体験向上

得られた経験

  • Web APIとの連携開発経験
  • GUIアプリケーションの設計と実装経験
  • ユーザーインターフェース設計の実践経験
  • GitHubでのプロジェクト管理経験

得られた成果物

  • 完全に動作するGUIデスクトップアプリケーション
  • GitHubでのポートフォリオとして活用可能なプロジェクト
  • 完全なPythonソースコード

次に学ぶべきこと

  • データベースへの保存機能を追加してアドバイス履歴を管理
  • 設定画面の実装でフォントサイズや色を変更可能にする
  • 他のAPIとの連携で名言や格言の取得機能を追加
  • CSVファイル出力機能でお気に入りアドバイスを保存

このプロジェクトから応用できること

  • 天気情報表示アプリをrequestsライブラリで天気APIと連携して開発
  • ニュース取得アプリをtkinterでリスト表示機能を追加して構築
  • 株価情報表示ツールをJSON処理技術を活用して作成
  • 翻訳アプリをHTTP通信技術で翻訳APIと連携して開発
  • API連携ツールの受託開発でクラウドワークス案件として活用

このHTTP通信とGUI開発技術を基盤として、様々な分野でのデータ取得と表示が必要なアプリケーションを開発することが可能です。特に、リアルタイムな情報表示が求められる業務では、高い価値を提供できる技術として活用できます。

この記事が気に入ったら
フォローしてね!

この記事が参考になった方はシェアしてね!
  • URLをコピーしました!

本コンテンツへの意見や質問

コメントする

目次