1.初めに
本記事ではモーダル画面を複数表示するコードについて紹介します。基本ベースは公式ドキュメントから作成し、これをclassに焼き直しました。その際に最も重要なことはclassコンポーネントにPage
を渡すことでした。
実行環境
- Python : 3.13.1
- Flet : 0.25.2
2.クラスコンポーネント化
公式ドキュメントではmain
関数内で
-
AlertDialog
を作成(以下、dlg_modal
と表現) - 作成した
dlg_modal
は以下の関数で表示/非表示
* 表示:page.open(dlg_modal)
* 非表示:page.close(dlg_modal)
-
ElevatedButton
を作成し、クリックイベントにpage.open(dlg_modal)
を設定(引数を設定するためラムダ式を使用) -
main
関数内でモーダルを閉じるイベントを定義
といったことをしています。これを、コンポーネント化しました。(モーダルを表示/非表示するイベントを登録したElevatedButton
の自作class)このclassの作成に当たり重要なことはpage
をclassの引数に渡すことです。(モーダルの表示/非表示を行うため。)
元ネタはこちらをご参照いただき、クラス化した結果が以下の通りです。
class My_Dialog(ElevatedButton):
def __init__(self, page: Page, task_id: int, task_name: str):
super().__init__()
self.page = page
self.task_id = task_id
self.task_name = task_name
self.text = f'Open modal Dialog {self.task_id}'
self.dlg_modal = AlertDialog(
modal=True,
title=Text(f'Please Confirm #{self.task_id}'),
content=Text(f'Task : {self.task_name}'),
actions=[
ElevatedButton(f'Yes #{self.task_id}', on_click=self.handle_event),
ElevatedButton(f'No #{self.task_id}', on_click=self.handle_event),
],
actions_alignment=MainAxisAlignment.END,
)
self.on_click = lambda e: self.page.open(self.dlg_modal)
def handle_event(self, e) -> None:
self.page.close(self.dlg_modal)
(クラスを定義するときに、よく忘れるのがコンストラクタ内のsuper().__init__()
ですね。)
上記コンポーネントではモーダルを表示/非表示のみのイベント登録をしていませんが、データ編集やデータ削除機能などを搭載するのが想定される用途です。
3.作成物
コンポーネント化されたコードを用いた例を以下に記載します。
import flet as ft
from flet import (
AlertDialog,
Column,
CrossAxisAlignment,
ElevatedButton,
MainAxisAlignment,
Page,
Text,
)
# テストデータ
tasks = [
{'id': 1, 'task_name': 'Sample1'},
{'id': 2, 'task_name': 'Sample2'},
{'id': 3, 'task_name': 'Sample3'},
{'id': 4, 'task_name': 'Sample4'},
{'id': 5, 'task_name': 'Sample5'},
{'id': 6, 'task_name': 'Sample6'},
{'id': 7, 'task_name': 'Sample7'},
{'id': 8, 'task_name': 'Sample8'},
]
class My_Dialog(ElevatedButton):
def __init__(self, page: Page, task_id: int, task_name: str):
super().__init__()
self.page = page
self.task_id = task_id
self.task_name = task_name
self.text = f'Open modal Dialog {self.task_id}'
self.dlg_modal = AlertDialog(
modal=True,
title=Text(f'Please Confirm #{self.task_id}'),
content=Text(f'Task : {self.task_name}'),
actions=[
ElevatedButton(f'Yes #{self.task_id}', on_click=self.handle_event),
ElevatedButton(f'No #{self.task_id}', on_click=self.handle_event),
],
actions_alignment=MainAxisAlignment.END,
)
self.on_click = lambda e: self.page.open(self.dlg_modal)
def handle_event(self, e) -> None:
self.page.close(self.dlg_modal)
def main(page: Page):
page.title = 'My Dialogs'
page.window.width = 600
page.horizontal_alignment = CrossAxisAlignment.CENTER
# モーダル設定済みのボタンを縦に並べる
modal_btns = Column()
for task in tasks:
tmp_modal = My_Dialog(page, task.get('id'), task.get('task_name'))
modal_btns.controls.append(tmp_modal)
page.add(modal_btns)
ft.app(target=main)
上記コードを実行し、ボタンを押下すると以下のようにモーダル画面が表示されます。(2個目のボタンを押下しています。)
最後に
比較的簡単にモーダルを表示させることができました。
試してはいませんが、モーダル画面の中でさらにモーダル画面の表示なんかできるのでしょうかね?(機会があれば試してみようと思います。)