4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Flet入門] Text・TextField・TextButtonで作る基本的なUI要素の実装方法

Posted at

はじめに

image.png

Fletは、Pythonを使ってクロスプラットフォームのUIアプリケーションを簡単に構築できるフレームワークです。Flutterをバックエンドに使用しているため、美しいマテリアルデザインのUIを持つアプリケーションを作成できます。

Fletの特徴は以下の通りです:

  • Pythonだけで完結: フロントエンドの知識(HTML、CSS、JavaScriptなど)が不要
  • クロスプラットフォーム: 同じコードでウェブ、デスクトップ、モバイルに対応
  • シンプルなAPI: 少ないコードで機能的なUIを構築可能
  • リアクティブ: データの変更に応じてUIが自動的に更新される

この記事では、Fletの基本的なテキスト系UI要素の使い方を紹介します。

環境構築

まずはFletをインストールしましょう。

pip install flet

基本的なテキスト系UI要素

Fletでは、様々なテキスト系UI要素が用意されています。ここでは、以下の4つを紹介します:

  1. Text: 基本的なテキスト表示
  2. TextField: テキスト入力フィールド
  3. TextButton: テキストボタン
  4. 様々なテキストスタイリング

実装例

以下のコードは、これらのUI要素を組み合わせた完全なサンプルアプリケーションです。

import flet as ft

def main(page: ft.Page):
    # ページの設定
    page.title = "Flet テキスト系UI要素のサンプル"
    page.theme_mode = ft.ThemeMode.LIGHT
    page.padding = 20
    
    # 長いテキストコンテンツを持つColumn作成(スクロール表示用)
    scroll_content = ft.Column(spacing=10)
    
    # 複数のテキスト要素を追加
    for i in range(1, 31):
        scroll_content.controls.append(
            ft.Text(f"テキスト行 {i}: サンプルテキストです。これはスクロールのテスト用です。", size=16)
        )
    
    # スクロール可能なコンテナ - スタイル適用のためにContainerでラップ
    scrollable_section = ft.Column([
        ft.Text("スクロールバーのサンプル", size=20, weight=ft.FontWeight.BOLD),
        ft.Container(
            content=ft.Column([
                # ListViewではなく、Columnとして配置
                ft.Container(
                    content=scroll_content,
                    height=300,  # 高さを制限
                    padding=20,
                    bgcolor=ft.Colors.BLUE_50,
                    border_radius=10,
                ),
            ]),
            bgcolor=ft.Colors.WHITE,
            border=ft.border.all(1, ft.Colors.GREY_400),
            border_radius=10,
            padding=10,
            margin=ft.margin.only(bottom=20),
        )
    ])
    
    # 1. 基本的なテキスト (Text)
    text_section = ft.Container(
        content=ft.Column(
            [
                ft.Text("1. 基本的なテキスト (Text)", size=20, weight=ft.FontWeight.BOLD),
                ft.Text("通常のテキスト表示です。"),
                ft.Text("サイズを変更したテキスト", size=25),
                ft.Text("太字のテキスト", weight=ft.FontWeight.BOLD),
                ft.Text("イタリック体のテキスト", italic=True),
                ft.Text("カラーを変更したテキスト", color=ft.Colors.RED),
                ft.Text("背景色を持つテキスト", bgcolor=ft.Colors.YELLOW_100),
                ft.Text("中央揃えのテキスト", text_align=ft.TextAlign.CENTER, width=400),
                ft.Text(
                    "長いテキストは自動的に折り返されます。" * 5,
                    width=400,
                ),
            ],
            spacing=10,
        ),
        padding=20,
        bgcolor=ft.Colors.BLUE_50,
        border_radius=10,
        margin=ft.margin.only(bottom=20),
    )
    
    # 2. テキストフィールド (TextField)
    def on_text_change(e):
        text_output.value = f"入力値: {text_field.value}"
        page.update()
    
    text_field = ft.TextField(
        label="名前を入力してください",
        hint_text="ここに入力",
        prefix_icon=ft.Icons.PERSON,
        helper_text="あなたのお名前を入力してください",
        on_change=on_text_change,
    )
    
    password_field = ft.TextField(
        label="パスワード",
        password=True,
        can_reveal_password=True,
    )
    
    multiline_field = ft.TextField(
        label="複数行のテキスト",
        multiline=True,
        min_lines=3,
        max_lines=5,
    )
    
    text_output = ft.Text("入力値: ")
    
    textfield_section = ft.Container(
        content=ft.Column(
            [
                ft.Text("2. テキストフィールド (TextField)", size=20, weight=ft.FontWeight.BOLD),
                text_field,
                password_field,
                multiline_field,
                text_output,
            ],
            spacing=20,
        ),
        padding=20,
        bgcolor=ft.Colors.GREEN_50,
        border_radius=10,
        margin=ft.margin.only(bottom=20),
    )
    
    # 3. テキストボタン (TextButton)
    def on_button_click(e):
        button_output.value = f"クリックされたボタン: {e.control.text}"
        page.update()
    
    simple_button = ft.TextButton("シンプルなテキストボタン", on_click=on_button_click)
    
    # スタイル付きボタン
    styled_button = ft.TextButton(
        "スタイル付きボタン",
        icon=ft.Icons.THUMB_UP,
        on_click=on_button_click,
        style=ft.ButtonStyle(
            color=ft.Colors.BLACK,
            bgcolor=ft.Colors.BLUE_100,
        ),
    )
    
    # ホバー効果
    hover_button = ft.ElevatedButton(
        "ホバー効果付きボタン",
        icon=ft.Icons.THUMB_UP,
        on_click=on_button_click,
    )
    
    disabled_button = ft.TextButton("無効化されたボタン", disabled=True)
    
    button_output = ft.Text("ボタンをクリックしてください")
    
    button_section = ft.Container(
        content=ft.Column(
            [
                ft.Text("3. テキストボタン (TextButton)", size=20, weight=ft.FontWeight.BOLD),
                ft.Row([simple_button, styled_button, hover_button, disabled_button], spacing=10),
                button_output,
            ],
            spacing=20,
        ),
        padding=20,
        bgcolor=ft.Colors.PURPLE_50,
        border_radius=10,
        margin=ft.margin.only(bottom=20),
    )
    
    # 4. さまざまなテキストスタイリング
    styling_section = ft.Container(
        content=ft.Column(
            [
                ft.Text("4. さまざまなテキストスタイリング", size=20, weight=ft.FontWeight.BOLD),
                ft.Text("フォントファミリー", font_family="Courier New"),
                
                # 下線付きテキスト - TextSpanとTextStyleを使用
                ft.Text(
                    spans=[
                        ft.TextSpan(
                            "テキストの装飾(下線)",
                            ft.TextStyle(decoration=ft.TextDecoration.UNDERLINE)
                        )
                    ]
                ),
                
                # 取り消し線 - TextSpanとTextStyleを使用
                ft.Text(
                    spans=[
                        ft.TextSpan(
                            "取り消し線",
                            ft.TextStyle(decoration=ft.TextDecoration.LINE_THROUGH)
                        )
                    ]
                ),
                
                # 文字間隔の調整 - TextSpanとTextStyleを使用
                ft.Text(
                    spans=[
                        ft.TextSpan(
                            "文字間隔の調整",
                            ft.TextStyle(letter_spacing=5)
                        )
                    ]
                ),
                
                # 背景と境界線 - Containerを使用
                ft.Container(
                    content=ft.Text("背景と境界線"),
                    bgcolor=ft.Colors.AMBER_100,
                    border=ft.border.all(1, ft.Colors.AMBER),
                    padding=10,
                ),
                
                # 影付きテキスト - Containerを使用
                ft.Container(
                    content=ft.Text("影付きテキスト"),
                    shadow=ft.BoxShadow(
                        blur_radius=2, 
                        color=ft.Colors.BLACK54
                    ),
                    padding=10,
                ),
                
                ft.Text(
                    "複数のスタイルを持つテキスト",
                    spans=[
                        ft.TextSpan(
                            "赤色のテキスト",
                            ft.TextStyle(color=ft.Colors.RED, italic=True),
                        ),
                        ft.TextSpan(
                            "青色のテキスト",
                            ft.TextStyle(color=ft.Colors.BLUE, weight=ft.FontWeight.BOLD),
                        ),
                    ],
                ),
                ft.SelectionArea(
                    content=ft.Text("このテキストは選択可能です。コピー&ペーストできます。"),
                ),
            ],
            spacing=10,
        ),
        padding=20,
        bgcolor=ft.Colors.ORANGE_50,
        border_radius=10,
    )
    
    # ページ全体のコンテンツ
    page_content = ft.Column([
        ft.Text("Fletの基本的なテキスト系UI要素", size=30, weight=ft.FontWeight.BOLD),
        scrollable_section,
        text_section,
        textfield_section,
        button_section,
        styling_section,
    ])
    
    # ページ全体をスクロール可能に
    page.scroll = "auto"
    page.add(page_content)


ft.app(target=main)

各UI要素の詳細説明

1. Text(基本的なテキスト)

Textウィジェットは最も基本的なテキスト表示コンポーネントです。

# 基本的な使い方
ft.Text("通常のテキスト表示です。")

# サイズ変更
ft.Text("サイズを変更したテキスト", size=25)

# スタイリング
ft.Text("太字のテキスト", weight=ft.FontWeight.BOLD)
ft.Text("イタリック体のテキスト", italic=True)
ft.Text("カラーを変更したテキスト", color=ft.Colors.RED)

2. TextField(テキストフィールド)

TextFieldは、ユーザーからのテキスト入力を受け付けるコンポーネントです。

# 基本的な使い方
ft.TextField(
    label="名前を入力してください",
    hint_text="ここに入力",
    prefix_icon=ft.Icons.PERSON,
    helper_text="あなたのお名前を入力してください",
    on_change=on_text_change,  # コールバック関数
)

# パスワード入力
ft.TextField(
    label="パスワード",
    password=True,
    can_reveal_password=True,
)

# 複数行入力
ft.TextField(
    label="複数行のテキスト",
    multiline=True,
    min_lines=3,
    max_lines=5,
)

3. TextButton(テキストボタン)

TextButtonは、クリック可能なテキストベースのボタンです。

# 基本的な使い方
ft.TextButton("シンプルなテキストボタン", on_click=on_button_click)

# スタイル付きボタン
ft.TextButton(
    "スタイル付きボタン",
    icon=ft.Icons.THUMB_UP,
    on_click=on_button_click,
    style=ft.ButtonStyle(
        color=ft.Colors.BLACK,
        bgcolor=ft.Colors.BLUE_100,
    ),
)

# 無効化されたボタン
ft.TextButton("無効化されたボタン", disabled=True)

4. 様々なテキストスタイリング

Fletでは、テキストに対して様々なスタイリングが可能です。

# フォントファミリーの変更
ft.Text("フォントファミリー", font_family="Courier New")

# テキストの装飾 - TextSpanとTextStyleを使用
ft.Text(
    spans=[
        ft.TextSpan(
            "テキストの装飾(下線)",
            ft.TextStyle(decoration=ft.TextDecoration.UNDERLINE)
        )
    ]
)

# 取り消し線 - TextSpanとTextStyleを使用
ft.Text(
    spans=[
        ft.TextSpan(
            "取り消し線",
            ft.TextStyle(decoration=ft.TextDecoration.LINE_THROUGH)
        )
    ]
)

# 文字間隔の調整 - TextSpanとTextStyleを使用
ft.Text(
    spans=[
        ft.TextSpan(
            "文字間隔の調整",
            ft.TextStyle(letter_spacing=5)
        )
    ]
)

# 複数のスタイルを持つテキスト
ft.Text(
    "複数のスタイルを持つテキスト",
    spans=[
        ft.TextSpan(
            "赤色のテキスト",
            ft.TextStyle(color=ft.Colors.RED, italic=True),
        ),
        ft.TextSpan(
            "青色のテキスト",
            ft.TextStyle(color=ft.Colors.BLUE, weight=ft.FontWeight.BOLD),
        ),
    ],
)

スクロール機能の実装

Fletでスクロール機能を実装するには、コンテナの高さを制限し、ページのスクロールプロパティを設定します。

# コンテナの高さを制限して、コンテンツがオーバーフローするようにする
container = ft.Container(
    content=content,
    height=300,  # 高さを制限
)

# ページ全体をスクロール可能に設定
page.scroll = "auto"  # または ft.ScrollMode.AUTO

スクロールモードには以下のオプションがあります:

  • AUTO:必要な時だけスクロールバーを表示
  • ALWAYS:常にスクロールバーを表示
  • HIDDEN:スクロールは可能だがスクロールバーは非表示
  • NONE(デフォルト):スクロール不可

注意点:Fletのバージョンによる違い

Fletは活発に開発が進められているフレームワークであり、バージョンによってAPIが変更されることがあります。このコードはFlet 0.25.0以降を前提としていますが、以下の変更点に注意してください:

  • ft.colorsft.Colorsへの変更
  • テキスト装飾(下線、取り消し線など)は直接設定できず、TextStyleを通して設定する必要がある
  • ListViewのプロパティと使用方法の変更

最新のAPIについては、公式ドキュメントを参照してください。

実行結果

このコードを実行すると、以下のようなアプリケーションが表示されます:

image.png

image.png

まとめ

image.png

Fletは、Pythonだけで美しいUIを持つクロスプラットフォームアプリケーションを簡単に構築できるフレームワークです。この記事では、基本的なテキスト系UI要素の使い方を紹介しました。

Fletの主な利点は以下の通りです:

  • シンプルなAPI: 少ないコードでリッチなUIを作成できます
  • クロスプラットフォーム: 同じコードで複数のプラットフォームに対応できます
  • Pythonだけで完結: フロントエンドの知識(HTML、CSS、JavaScript)が不要です
  • リアクティブ: データの変更に応じて自動的にUIを更新します

Fletはまだ比較的新しいフレームワークですが、シンプルさと強力な機能を兼ね備えており、今後さらに発展していくことが期待されます。

参考リンク

4
4
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
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?