1
0

PythonでリッチなCUIアプリケーションを作ってみた

Last updated at Posted at 2024-05-30

はじめに

Pythonには、CUIアプリケーションを作成するための様々なライブラリがある。その中でも、Richライブラリは、美しく洗練されたCUIアプリケーションを作成するための強力なツールである。

なんとなくリッチなCUIに興味があったから触ってみたが、長い処理を行っている場合などは、使うとユーザーフレンドリーでめちゃよさそうだと感じた。

本記事では、Richライブラリを使用して、タスク管理ツールを作成する過程を紹介する。

Richライブラリの概要

Richライブラリは、CUIアプリケーションに色、スタイル、および高度なフォーマットを追加するためのPythonライブラリである。主な機能には以下のようなものがある。

  • カラフルな出力
  • テーブルの作成
  • プログレスバー
  • シンタックスハイライト
  • マークダウンのレンダリング

Richライブラリを使用することで、ユーザーフレンドリーで視覚的に優れたCUIアプリケーションを簡単に作成できる。

タスク管理ツールの作成

GitHubのコード

基本機能の実装

まず、タスク管理ツールの基本機能を実装する。タスクを追加、削除、および一覧表示する機能を追加する。

from rich import print
from rich.console import Console
from rich.table import Table
from rich.prompt import Prompt

tasks = []

def display_tasks():
    table = Table(title="タスク一覧")
    table.add_column("ID", style="cyan")
    table.add_column("タスク名", style="magenta")
    table.add_column("優先度", style="green")

    for i, task in enumerate(tasks, start=1):
        priority = "" if task["priority"] == "high" else "" if task["priority"] == "medium" else ""
        table.add_row(str(i), task["name"], priority)

    console = Console()
    console.print(table)

def add_task():
    name = Prompt.ask("タスク名を入力してください")
    priority = Prompt.ask("優先度を入力してください", choices=["high", "medium", "low"])
    tasks.append({"name": name, "priority": priority})
    print("[bold green]タスクが追加されました[/bold green]")

def delete_task():
    task_id = Prompt.ask("削除するタスクのIDを入力してください", default="0")
    if task_id.isdigit() and 1 <= int(task_id) <= len(tasks):
        tasks.pop(int(task_id) - 1)
        print("[bold green]タスクが削除されました[/bold green]")
    else:
        print("[bold red]無効なタスクIDです[/bold red]")

Tableクラスを使用して、タスクの一覧表示を見やすくフォーマットしている。また、Promptクラスを使用して、ユーザー入力を簡単に処理している。

スピナーの追加

処理中にスピナーを表示することで、ユーザーに処理の進行状況を伝えることができる。ここでは、Haloライブラリを使用してスピナーを追加する。

from halo import Halo

def add_task(console):
    name = Prompt.ask("タスク名を入力してください")
    priority = Prompt.ask("優先度を入力してください", choices=["high", "medium", "low"])
    with console.status("[bold green]タスクを追加中..."):
        tasks.append({"name": name, "priority": priority})
    print("[bold green]タスクが追加されました[/bold green]")

def delete_task(console):
    task_id = Prompt.ask("削除するタスクのIDを入力してください", default="0")
    with console.status("[bold green]タスクを削除中..."):
        if task_id.isdigit() and 1 <= int(task_id) <= len(tasks):
            tasks.pop(int(task_id) - 1)
            print("[bold green]タスクが削除されました[/bold green]")
        else:
            print("[bold red]無効なタスクIDです[/bold red]")

スピナーを表示しながらユーザー入力を受け付けるのは、少し工夫が必要である。単純にHaloのコンテキストマネージャー内でPromptを使用すると、入力プロンプトが表示されなくなってしまう。

ヘルプ機能の追加

ユーザーがツールの使い方を理解しやすいように、ヘルプ機能を追加する。

def display_help():
    help_text = """
    タスク管理ツール - 使い方

    このツールでは、以下のアクションが可能です:
    1. タスクを追加: 新しいタスクを追加します。タスク名と優先度を入力してください。
    2. タスクを削除: 既存のタスクを削除します。削除するタスクのIDを入力してください。
    3. 終了: ツールを終了します。

    アクション番号を入力し、Enterキーを押してください。
    """
    print(help_text)

完成したコード

from rich import print
from rich.console import Console
from rich.table import Table
from rich.prompt import Prompt
from halo import Halo

tasks = []

def display_tasks():
    table = Table(title="タスク一覧")
    table.add_column("ID", style="cyan")
    table.add_column("タスク名", style="magenta")
    table.add_column("優先度", style="green")

    for i, task in enumerate(tasks, start=1):
        priority = "" if task["priority"] == "high" else "" if task["priority"] == "medium" else ""
        table.add_row(str(i), task["name"], priority)

    console = Console()
    console.print(table)

def add_task(console):
    name = Prompt.ask("タスク名を入力してください")
    priority = Prompt.ask("優先度を入力してください", choices=["high", "medium", "low"])
    with console.status("[bold green]タスクを追加中..."):
        tasks.append({"name": name, "priority": priority})
    print("[bold green]タスクが追加されました[/bold green]")

def delete_task(console):
    task_id = Prompt.ask("削除するタスクのIDを入力してください", default="0")
    with console.status("[bold green]タスクを削除中..."):
        if task_id.isdigit() and 1 <= int(task_id) <= len(tasks):
            tasks.pop(int(task_id) - 1)
            print("[bold green]タスクが削除されました[/bold green]")
        else:
            print("[bold red]無効なタスクIDです[/bold red]")

def display_help():
    help_text = """
    タスク管理ツール - 使い方

    このツールでは、以下のアクションが可能です:
    1. タスクを追加: 新しいタスクを追加します。タスク名と優先度を入力してください。
    2. タスクを削除: 既存のタスクを削除します。削除するタスクのIDを入力してください。
    3. 終了: ツールを終了します。

    アクション番号を入力し、Enterキーを押してください。
    """
    print(help_text)

def main():
    console = Console()

    while True:
        display_tasks()
        print("\n[bold blue]アクション:[/bold blue]")
        print("1. タスクを追加")
        print("2. タスクを削除")
        print("3. 終了")
        print("4. ヘルプ")

        def prompt_with_spinner():
            spinner = Halo(text="\nアクション番号を選択してください", spinner={
                "interval": 120,
                "frames": [
                    "", "", "", "", "", "", "", "", "", ""
                ]
            })
            spinner.start()
            action = ""
            while action not in ["1", "2", "3", "4"]:
                action = input()
                print(action)  # 入力文字をエコーバックする
            spinner.stop()
            return action

        action = prompt_with_spinner()

        if action == "1":
            add_task(console=console)
        elif action == "2":
            delete_task(console=console)
        elif action == "3":
            print("[bold green]タスク管理ツールを終了します[/bold green]")
            break
        elif action == "4":
            display_help()

if __name__ == "__main__":
    main()

まとめ

本記事では、Pythonのrichライブラリを使用して、タスク管理ツールを作成する過程を紹介した。Richライブラリを使用することで、美しく洗練されたっぽいCUIアプリケーションを簡単に作成できる。

また、Haloライブラリを使用してスピナーを追加し、処理中の視覚的なフィードバックを提供することで、ユーザー体験を向上させることができる。

また、pip install などの動きを作成している背景を想像でき、面白いと感じた。

スピナーとユーザー入力を同時に扱うには、工夫が必要である。本記事では、その問題に対する完全な解決策を提示することはできなかったが、今後の課題としたい。

簡単に導入が可能であるので、自分のプロジェクトにRichライブラリを導入して、ユーザーフレンドリーで美しいCUIアプリケーションを作成しようと思う。

また、ほかの言語でも必ずライブラリがあると感じたので、業務でよく使うNodeなどは改めて触ってみようと思う。

1
0
2

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
1
0