[Flet入門] 基本的な表示系UI要素の実装ガイド

Fletで基本的な表示系UI要素を実装する記事を書きました。Image、Icon、ProgressBar、ProgressRingなどPythonだけで美しいUIを構築する方法を簡潔に解説。バージョンによる違いにも触れています。Pythonでデスクトップ/Webアプリを作る方に参考になれば。📝

## はじめに

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/404c64f1-9e8a-4c14-a080-8008f0767c17.png)

前回の記事では、Fletのテキスト系UI要素を紹介しました。今回は、基本的な表示系UI要素に焦点を当てます：

- **Image**: 画像の表示
- **Icon**: アイコンの表示
- **ProgressBar, ProgressRing**: 進捗表示
- **Divider**: 区切り線

Fletは、Pythonだけでクロスプラットフォームのアプリケーションを簡単に構築できるフレームワークです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/66d0ce4c-54b6-4655-bb00-913622dec214.png)


## 環境構築

```bash
pip install flet
```

**注意**: Fletはバージョンによって大きくAPIが異なります。
- バージョン0.25.0以降: `ft.colors` → `ft.Colors`, `ft.icons` → `ft.Icons` 
- 各バージョンで利用できるウィジェットやパラメータが異なる場合があります

この記事では基本的なウィジェットに絞って解説します。

## 基本サンプルコード

シンプルに動作する基本コードです：

```python
import flet as ft

def main(page: ft.Page):
    page.title = "Flet 基本UI要素"
    page.padding = 20
    
    # ----- 1. Image -----
    page.add(
        ft.Text("1. Image (画像)", size=20, weight=ft.FontWeight.BOLD),
        
        # ネットワーク画像
        ft.Text("ネットワーク画像:"),
        ft.Image(
            src="https://picsum.photos/300/200",
            width=300,
            height=200,
        ),
        
        # 画像の表示形式
        ft.Text("画像の表示形式:"),
        ft.Row([
            # CONTAIN形式
            ft.Container(
                content=ft.Image(
                    src="https://picsum.photos/300/200?random=1",
                    width=150,
                    height=100,
                    fit=ft.ImageFit.CONTAIN,
                ),
                bgcolor=ft.Colors.AMBER_100,
                width=150,
                height=100,
            ),
            # COVER形式
            ft.Container(
                content=ft.Image(
                    src="https://picsum.photos/300/200?random=2",
                    width=150,
                    height=100,
                    fit=ft.ImageFit.COVER,
                ),
                bgcolor=ft.Colors.AMBER_100,
                width=150,
                height=100,
            ),
        ]),
    )
    
    # ----- 2. Icon -----
    page.add(
        ft.Container(padding=10),  # 余白用
        ft.Text("2. Icon (アイコン)", size=20, weight=ft.FontWeight.BOLD),
        ft.Text("マテリアルアイコン:"),
        ft.Row([
            ft.Icon(name=ft.Icons.FAVORITE, color=ft.Colors.RED, size=40),
            ft.Icon(name=ft.Icons.AUDIOTRACK, color=ft.Colors.GREEN, size=40),
            ft.Icon(name=ft.Icons.CLOUD, color=ft.Colors.BLUE, size=40),
        ], spacing=30),
    )
    
    # ----- 3. ProgressBar & ProgressRing -----
    page.add(
        ft.Container(padding=10),  # 余白用
        ft.Text("3. ProgressBar & ProgressRing (進捗表示)", size=20, weight=ft.FontWeight.BOLD),
        
        # ProgressBar
        ft.Text("ProgressBar (水平の進捗バー):"),
        ft.ProgressBar(width=400, value=0.6),  # 60%の進捗
        
        ft.Container(padding=10),  # 余白用
        ft.Text("不定の進捗バー:"),
        ft.ProgressBar(width=400),  # 不定の進捗
        
        # ProgressRing
        ft.Container(padding=10),  # 余白用
        ft.Text("ProgressRing (円形の進捗表示):"),
        ft.ProgressRing(value=0.6),  # 60%の進捗
        
        ft.Container(padding=10),  # 余白用
        ft.Text("不定の進捗リング:"),
        ft.ProgressRing(),  # 不定の進捗
    )
    
    # ----- 4. Divider -----
    page.add(
        ft.Container(padding=10),  # 余白用
        ft.Text("4. Divider (区切り線)", size=20, weight=ft.FontWeight.BOLD),
        
        # 水平区切り線
        ft.Text("水平の区切り線:"),
        ft.Text("区切り線の上のテキスト"),
        ft.Divider(),
        ft.Text("区切り線の下のテキスト"),
        
        # カスタム区切り線
        ft.Container(padding=10),  # 余白用
        ft.Text("カスタム区切り線:"),
        ft.Divider(
            height=20,
            thickness=3,
            color=ft.Colors.BLUE,
        ),
        
        # 垂直区切り線
        ft.Container(padding=10),  # 余白用
        ft.Text("垂直の区切り線:"),
        ft.Row([
            ft.Text("左側のテキスト"),
            ft.VerticalDivider(
                width=30,
                thickness=2,
                color=ft.Colors.RED,
            ),
            ft.Text("右側のテキスト"),
        ], height=50),
    )

ft.app(target=main)
```

## 各UI要素の解説

### 1. Image (画像)

`Image`ウィジェットは画像を表示するためのコンポーネントです。

```python
# 基本的な使い方
ft.Image(
    src="https://example.com/image.jpg",  # 画像のURL
    width=300,                        # 幅
    height=200,                       # 高さ
)

# 表示形式を指定
ft.Image(
    src="https://example.com/image.jpg",
    width=300,
    height=200,
    fit=ft.ImageFit.COVER,  # 表示形式
)
```

**補足**: サンプルコードでは [Lorem Picsum](https://picsum.photos/) というサービスを使用しています。これは開発者向けのプレースホルダー画像を提供する無料サービスで、URLに希望するサイズを指定するだけで簡単に画像を取得できます（例: `https://picsum.photos/300/200`）。テスト用に便利です。

**主なfit属性**:
- `CONTAIN`: アスペクト比を保持してコンテナ内に収める
- `COVER`: アスペクト比を保持してコンテナを埋める
- `FILL`: アスペクト比を無視してコンテナサイズに合わせる
- `NONE`: サイズ調整なし

### 2. Icon (アイコン)

`Icon`ウィジェットはマテリアルデザインのアイコンを表示します。

```python
# 基本的な使い方
ft.Icon(
    name=ft.Icons.FAVORITE,  # アイコン名
    color=ft.Colors.RED,     # 色
    size=40,                 # サイズ
)
```

Fletには700以上のマテリアルアイコンが用意されています。

### 3. 進捗表示 (ProgressBar & ProgressRing)

#### ProgressBar

`ProgressBar`は水平方向の進捗バーを表示します。

```python
# 進捗値あり（0〜1の値）
ft.ProgressBar(width=400, value=0.5)  # 50%の進捗

# 不定の進捗バー
ft.ProgressBar(width=400)
```

#### ProgressRing

`ProgressRing`は円形の進捗インジケーターを表示します。

```python
# 進捗値あり
ft.ProgressRing(value=0.7)  # 70%の進捗

# 不定の進捗リング
ft.ProgressRing()
```

### 4. Divider (区切り線)

`Divider`は水平または垂直の区切り線を表示します。

```python
# 基本的な水平区切り線
ft.Divider()

# カスタムスタイルの水平区切り線
ft.Divider(
    height=20,       # 区切り線の高さ（余白含む）
    thickness=3,     # 線の太さ
    color=ft.Colors.BLUE,  # 線の色
)

# 垂直区切り線
ft.VerticalDivider(
    width=30,        # 区切り線の幅（余白含む）
    thickness=2,     # 線の太さ
    color=ft.Colors.RED,   # 線の色
)
```

## 高度なUI要素

Fletには、この記事で紹介した基本要素以外にも多くのUI要素があります。例えば：

- **Tooltip**: ホバー時に表示されるヒント
- **Badge**: 通知バッジ
- **Banner**: 通知バナー
- **Card**: カード形式のコンテナ

これらの要素はFletのバージョンによって実装方法が異なる場合があります。公式ドキュメントを参照して、お使いのバージョンに合わせた実装を行いましょう。

## 実用的なヒント

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/d0713bed-5a47-413d-a91a-37ddd1c301bf.png)

- **コンテナの活用**: `Container`でラップすることで背景色、余白などを追加
- **レイアウト**: `Row`と`Column`を組み合わせて柔軟なレイアウトを実現
- **スタイリング**: `Colors`を活用して視覚的な魅力を高める
- **バージョン互換性**: エラーが出た場合はバージョンを確認

## まとめ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/7640c86c-a85c-4b74-a2f6-2805ce036173.png)

Fletを使えば、Pythonだけでクロスプラットフォームの美しいUIを持つアプリケーションを簡単に構築できます。今回紹介した基本的な表示系要素を使いこなすことで、より魅力的なアプリケーションの作成が可能になります。

- **シンプル**: 少ないコードで美しいUIを構築
- **クロスプラットフォーム**: 同じコードで様々なプラットフォームに対応
- **Pythonのみ**: フロントエンド技術の知識不要

より詳細な情報は[Flet公式ドキュメント](https://flet.dev/docs/)を参照してください。

## 免責事項
本記事の作成にあたり、文章や図解の生成にClaude Sonnet, Napkin AIを、ファクトチェックにGensparkを活用しました。最終的な編集と確認は筆者が行っています。