はじめに
Pythonのフレームワーク「Flet」について一から調べたので、備忘録として最初に知っておくとよさそうな基本知識をまとめてみた😊
この記事で解決したいこと
✅はじめてFlet開発するときに困らないようにする!
- Fletの基本概念
- 画面の作り方
- 画面の制御
今回のゴール
✅基礎知識を把握し、前回作ったカウンターアプリの仕組みを理解できるようになる!
【補足】カウンターアプリのソースコード
counter.py
import flet as ft
def main(page: ft.Page):
page.title = "Flet counter example"
page.vertical_alignment = ft.MainAxisAlignment.CENTER
txt_number = ft.TextField(value="0", text_align=ft.TextAlign.RIGHT, width=100)
def minus_click(e):
txt_number.value = str(int(txt_number.value) - 1)
page.update()
def plus_click(e):
txt_number.value = str(int(txt_number.value) + 1)
page.update()
page.add(
ft.Row(
[
ft.IconButton(ft.icons.REMOVE, on_click=minus_click),
txt_number,
ft.IconButton(ft.icons.ADD, on_click=plus_click),
],
alignment=ft.MainAxisAlignment.CENTER,
)
)
ft.app(target=main)
Fletの概念を理解する
前回作ったカウンターアプリを例に基本的な概念を理解していく😊
プログラムの基本構成
✅とりあえずエントリーポイントを用意すれば起動できる。
-
ft.app(target=任意の関数名)
でエントリーポイントが設定できる。
カウンターアプリの場合
import flet as ft
def main(page: ft.Page):
# TODO:ここに処理を書く
# ボタンの追加とか
# ✅エントリーポイントはmainとする
ft.app(target=main)
簡単なプログラムなら1ファイルだけで完結する
画面の1パーツ = コントロールと呼ぶ
✅「テキスト」「ボタン」などのパーツをコントロールと呼ぶ。
1コントロールで改行される
例:textコントロール × 3
ただしRowなど一部のコントロールは入れ子にできる
例:Rowの中にtextが3つ入っている
カウンターアプリの場合
「Row」の中に「ボタン」と「テキスト」が配置されている(入れ子)。
pageとview
✅アプリには必ずpageとviewが存在する。
引用:https://flet.dev/blog/navigation-and-routing/#page-views
page
✅画面全体を管理するもの
pageのプロパティ一覧
プロパティ名 | 概要 |
---|---|
auto_scroll | 子要素が更新されたときにスクロールバーの位置を自動的に移動するかどうかを指定する。Falseにすると、scroll_to()メソッドが使える。 |
app_bar | ページの上部に表示するAppBarコントロールを指定する。 |
banner | ページの上部に表示するBannerコントロールを指定する。 |
bgcolor | ページの背景色を指定する。色の値は16進数やflet.colorsモジュールの名前で指定できる。 |
client_ip | Webでのみ有効。接続しているユーザーのIPアドレスを取得できる。 |
client_user_agent | Webでのみ有効。接続しているユーザーのブラウザの詳細を取得できる。 |
controls | ページに表示するControlのリストを指定する。page.controls.append()やpage.add()で追加できる。 |
dark_theme | ダークテーマをカスタマイズするためにtheme.Themeのインスタンスを指定する。 |
dialog | 表示するAlertDialogコントロールを指定する。 |
floating_action_button | ページの内容の上に表示するFloatingActionButtonコントロールを指定する。 |
fonts | カスタムフォントをインポートして、Text.font_familyやtheme.font_familyで使えるようにするために、フォント名とフォントファイルのURLの辞書を指定する。フォントファイルは外部リソースやアプリケーションアセットからインポートできる。 |
height | WebページやネイティブOSウィンドウの内容領域の高さを取得できる。このプロパティは読み取り専用で、page.on_resizeハンドラーでよく使われる。 |
horizontal_alignment |
子要素を水平方向にどのように配置するかを指定する。デフォルト値はCrossAxisAlignment.STARTで、ページの左側に配置されることを意味する。プロパティ値はCrossAxisAlignment列挙型で、以下の値がある:
START (default) CENTER END STRETCH BASELINE |
on_scroll_interval | on_scrollイベントの間引き時間(ミリ秒)を指定する。デフォルトは10. |
overlay | ページの内容の上に重ねて表示するControlのリストを指定する。 |
padding | ページの内容とその端との間隔を指定する。デフォルト値は各辺から10ピクセルである。ゼロパディングに設定するには:page.padding = 0. 詳細と可能な値については、Container.paddingを参照してください。 |
platform |
アプリケーションが動作しているオペレーティング・システム:
ios android macos linux windows |
pubsub | アプリケーションセッション間でメッセージをやり取りするためのシンプルなPubSub実装です。 |
pwa | アプリケーションがProgressive Web App (PWA)として実行されているかどうかを示す真偽値です。読み取り専用です。 |
route | ページのナビゲーションルートを取得または設定します。ナビゲーションとルーティングのセクションで詳細と例を参照してください。 |
rtl | テキストの方向を右から左に設定するかどうかを指定します。デフォルトはFalseです。 |
scroll |
ページに垂直方向のスクロールを有効にして、内容のオーバーフローを防ぎます。プロパティ値はオプションのScrollMode列挙型で、Noneがデフォルトです。
None (デフォルト) - Rowはスクロールできず、内容がオーバーフローする可能性がある。 AUTO - スクロールが有効で、スクロールバーはスクロール時にのみ表示される。 ADAPTIVE - スクロールが有効で、スクロールバーはWebやデスクトップでアプリを実行しているときに常に表示される。 ALWAYS - スクロールが有効で、スクロールバーは常に表示される。 HIDDEN - スクロールが有効だが、スクロールバーは常に隠れている。 |
session_id | ユーザーセッションの一意なIDです。このプロパティは読み取り専用です。 |
spacing | ページ上のコントロール間の垂直方向の間隔を指定します。デフォルト値は10ピクセルです。間隔は、alignmentがstart, end, centerの場合にのみ適用されます。 |
splash | ページの内容の上に表示するControlを指定します。ProgressBarやProgressRingなどを使って、長時間かかる操作のインジケーターとして使えます。 |
show_semantics_debugger | フレームワークが報告するアクセシビリティ情報を表示するオーバーレイを有効にするかどうかを指定します。 |
theme | ライトテーマをカスタマイズするためにtheme.Themeのインスタンスを指定します。現在、テーマは「シード」色から自動的に生成されることしかできません。 |
theme_mode |
ページのテーマ。
プロパティの値はオプションのThemeMode列挙型で、デフォルトはSYSTEMです。 サポートされる値:SYSTEM(デフォルト)、LIGHTまたはDARK。 |
title | 例えば、ブラウザやネイティブOSのウィンドウのタイトル |
vertical_alignment |
子要素の縦方向の設定。
例えば、デフォルトの MainAxisAlignment.START は、子コントロールをページの上部に配置します。 プロパティ値はMainAxisAlignment列挙型で、以下の値があります: START (default) END CENTER SPACE_BETWEEN SPACE_AROUND SPACE_EVENLY |
views |
ナビゲーション履歴を作成するためのビューコントロールのリスト。
リストの最後のビューがページに表示されます。 最初のビューは、ポップアップできない「ルート」ビューです。 |
web | アプリケーションがWebブラウザで実行されているかどうかを示す真偽値。 |
width | WebページやネイティブOSウィンドウの内容領域の幅を取得できる。このプロパティは読み取り専用で、page.on_resizeハンドラーでよく使われる。 |
window_always_on_top | ️デスクトップのみ。ウィンドウが他のウィンドウの上に常に表示されるかどうかを設定する。デフォルトはFalse。 |
window_bgcolor | ️デスクトップのみ。アプリケーションウィンドウの背景色を設定する。page.bgcolorと一緒に使って、ウィンドウを透明にすることができる。 |
window_focused | ️デスクトップのみ。Fletアプリを含むネイティブOSウィンドウにフォーカスを設定するかどうかを設定する。Trueにすると、ウィンドウがフォアグラウンドに移動する。 |
window_frameless | ️デスクトップのみ。アプリウィンドウをフレームレスにするかどうかを設定する。Trueにすると、タイトルバーや境界線がなくなる。 |
window_fullscreen | ️デスクトップのみ。アプリのネイティブOSウィンドウをフルスクリーンモードに切り替えるかどうかを設定する。デフォルトはFalse。 |
window_height | ️デスクトップのみ。Fletアプリを含むネイティブOSウィンドウの高さを取得または設定する。 |
window_left | ️デスクトップのみ。Fletアプリを含むネイティブOSウィンドウの水平位置を取得または設定する。画面の左端からの仮想ピクセル単位の距離である。 |
window_maximizable | ️デスクトップのみ。「最大化」ボタンを表示/無効化するかどうかを設定する。デフォルトはTrue。 |
window_maximized | ️デスクトップのみ。Fletアプリを含むネイティブOSウィンドウが最大化されているかどうかを示す真偽値。このプロパティをTrueに設定すると、プログラム的にウィンドウを最大化し、Falseに設定すると元に戻すことができる。 |
window_max_height | ️デスクトップのみ。Fletアプリを含むネイティブOSウィンドウの最大高さを取得または設定する。 |
window_max_width | ️デスクトップのみ。Fletアプリを含むネイティブOSウィンドウの最大幅を取得または設定する。 |
window_minimizable | ️デスクトップのみ。「最小化」ボタンを表示/無効化するかどうかを設定する。デフォルトはTrue。 |
window_minimized | ️デスクトップのみ。Fletアプリを含むネイティブOSウィンドウが最小化されているかどうかを示す真偽値。このプロパティをTrueに設定すると、プログラム的にウィンドウを最小化し、Falseに設定すると元に戻すことができる。 |
window_min_height | ️デスクトップのみ。Fletアプリを含むネイティブOSウィンドウの最小高さを取得または設定する。 |
window_min_width | ️デスクトップのみ。Fletアプリを含むネイティブOSウィンドウの最小幅を取得または設定する。 |
window_movable | ️デスクトップのみ。macOSのみ。ユーザーがFletアプリを含むネイティブOSウィンドウの位置を変更できるかどうかを設定する。デフォルトはTrue。 |
window_opacity | ️デスクトップのみ。ネイティブOSウィンドウの不透明度を設定する。値は0.0(完全に透明)から1.0(完全に不透明)の間でなければならない。 |
window_resizable | ️デスクトップのみ。ユーザーがFletアプリを含むネイティブOSウィンドウのサイズを変更できるかどうかを設定する。デフォルトはTrue。 |
window_title_bar_hidden | ️デスクトップのみ。タイトルバーを非表示にするかどうかを設定する。WindowDragAreaコントロールを使って、タイトルバーが隠れているときにアプリウィンドウを移動できるようにすることができる。 |
window_title_bar_buttons_hidden | ️デスクトップのみ。タイトルバーが隠れているときに、ウィンドウ操作ボタンを非表示にするかどうかを設定する。macOSのみ。 |
window_top | ️デスクトップのみ。Fletアプリを含むネイティブOSウィンドウの垂直位置を取得または設定する。画面の上端からの仮想ピクセル単位の距離である。 |
window_prevent_close | ️デスクトップのみ。「閉じる」シグナルをインターセプトするかどうかを設定する。page.on_window_event (close) イベントハンドラーと page.window_destroy () を使って、アプリ終了確認ロジックを実装できる - page.window_destroy () のコード例を参照してください。 |
window_progress_value | ️デスクトップのみ。タスクバー(Windows)やDock(macOS)のアプリケーションボタンにプログレスバーを表示するための0.0から1.0までの値。 |
window_skip_task_bar | ️デスクトップのみ。タスクバー(Windows)やDock(macOS)からアプリケーションを隠すかどうかを設定する。 |
window_visible | デスクトップのみ。Trueに設定すると、アプリケーション・ウィンドウが表示されます。アプリが非表示のウィンドウで起動している場合に使用します。 |
window_width | デスクトップのみ。Fletアプリを含むネイティブOSウィンドウの幅を取得または設定します。 |
view
✅最上位のコントロール
すべてのコントロール(テキスト、ボタンなど)はviewの中に配置していくイメージ。
アプリを起動すると自動的にviewが1つ生成される。
viewのプロパティ一覧
プロパティ名 | 概要 |
---|---|
appbar | ページの上部に表示するAppBarコントロールを指定する。 |
auto_scroll | 子要素が更新されたときにスクロールバーの位置を自動的に移動するかどうかを指定する。Falseにすると、scroll_to()メソッドが使える。 |
bgcolor | ページの背景色を指定する。色の値は16進数やflet.colorsモジュールの名前で指定できる。 |
controls | ページに表示するControlのリストを指定する。page.controls.append()やpage.add()で追加できる。 |
fullscreen_dialog | このビューがフルスクリーンダイアログかどうかを示す真偽値。MaterialとCupertinoでは、フルスクリーンであるということは、アプリバーに戻るボタンではなく閉じるボタンが表示されることを意味する。iOSでは、ダイアログの遷移は異なってアニメーションし、またバックスワイプジェスチャーで閉じることができない。 |
route | ビューのルート - Fletでは使用されていませんが、ビューがポップしたときにpage.routeを更新するためにユーザープログラムで使用することができます。 |
floating_action_button | ページの内容の上に表示するFloatingActionButtonコントロールを指定する。 |
horizontal_alignment |
子要素を水平方向にどのように配置するかを指定する。デフォルト値はCrossAxisAlignment.STARTで、ページの左側に配置されることを意味する。プロパティ値はCrossAxisAlignment列挙型で、以下の値がある:
START (default) CENTER END STRETCH BASELINE |
on_scroll_interval | on_scrollイベントの間引き時間(ミリ秒)を指定する。デフォルトは10. |
padding | ページの内容とその端との間隔を指定する。デフォルト値は各辺から10ピクセルである。ゼロパディングに設定するには:page.padding = 0. 詳細と可能な値については、Container.paddingを参照してください。 |
scroll |
コンテンツのオーバーフローを防ぐために、ページの垂直スクロールを有効にします。
プロパティ値はオプションの ScrollMode 列挙型で、デフォルトは None です。 サポートされる値: None (デフォルト) - 行はスクロール不可能で、コンテンツがオーバーフローする可能性があります。 AUTO - スクロールが有効で、スクロールが発生したときにのみスクロール バーが表示されます。 ADAPTIVE - ウェブまたはデスクトップとしてアプリを実行している場合、スクロールが有効になり、スクロールバーが常に表示されます。 ALWAYS - スクロールが有効で、スクロールバーが常に表示されます。 HIDDEN - スクロールは有効ですが、スクロールバーは常に非表示です。 |
spacing | ページ上のコントロール間の垂直方向の間隔を指定します。デフォルト値は10ピクセルです。間隔は、alignmentがstart, end, centerの場合にのみ適用されます。 |
vertical_alignment |
子要素を垂直方向にどのように配置するかを指定する。デフォルト値はMainAxisAlignment.STARTで、ページの上部に配置されることを意味する。プロパティ値はMainAxisAlignment列挙型で、以下の値がある:
START (default) END CENTER SPACE_BETWEEN SPACE_AROUND SPACE_EVENLY |
カウンターアプリの場合
1つのviewの中にRowが配置されているシンプルな構成。
(viewはpageによって管理されているが、今回はあまり意識する必要はない。)
内部的にはWebアプリとして動作している
✅ネイティブOSのウィンドウで起動していても、内蔵のWebサーバーがバックグラウンドで起動している。
画面の作り方
コントロールを画面に追加する方法
✅コントロールを画面に追加するには、「コントロールの追加」と「画面への反映」が必要。
【パターン1】追加してから反映するappend, update
append
でコントロールを追加して、update
で画面へ反映する方法。
import flet as ft
def main(page: ft.Page):
t = ft.Text(value="Hello, world!", color="green")
# テキストを追加
page.controls.append(t)
# 画面に反映
page.update()
ft.app(target=main)
【パターン2】追加と反映をまとめて行うadd
add
を使えばappend
とupdate
をまとめて実行できる。
import flet as ft
def main(page: ft.Page):
t = ft.Text(value="Hello, world!", color="green")
# テキストを追加、画面に反映
page.add(t)
ft.app(target=main)
add
でOK!
カウンターアプリの場合
コントロール「Row」を画面に追加している。
import flet as ft
def main(page: ft.Page):
page.title = "Flet counter example"
page.vertical_alignment = ft.MainAxisAlignment.CENTER
txt_number = ft.TextField(value="0", text_align=ft.TextAlign.RIGHT, width=100)
def minus_click(e):
txt_number.value = str(int(txt_number.value) - 1)
page.update()
def plus_click(e):
txt_number.value = str(int(txt_number.value) + 1)
page.update()
# ✅ここでコントロールRowを画面に追加している!
page.add(
# Rowを画面に追加
ft.Row(
[
# Rowの中身はボタン、テキスト、ボタン
ft.IconButton(ft.icons.REMOVE, on_click=minus_click),
txt_number,
ft.IconButton(ft.icons.ADD, on_click=plus_click),
],
alignment=ft.MainAxisAlignment.CENTER,
)
)
ft.app(target=main)
コントロールの更新
✅すでに画面にあるコントロールの値(プロパティ)を更新するにはpage.update()
を実行する。
txt = ft.TextField(value="あいうえお")
page.add(t)
# ✅すでに画面にあるtxtコントロールの値を更新する
txt.value = "かきくけこ"
page.update()
update
が必要!
カウンターアプリの場合
カウンターの値を更新するためにpage.update()
を使用している。
import flet as ft
def main(page: ft.Page):
page.title = "Flet counter example"
page.vertical_alignment = ft.MainAxisAlignment.CENTER
txt_number = ft.TextField(value="0", text_align=ft.TextAlign.RIGHT, width=100)
# マイナスボタンをクリック
def minus_click(e):
# ✅値を-1して更新
txt_number.value = str(int(txt_number.value) - 1)
page.update()
# プラスボタンをクリック
def plus_click(e):
# ✅値を+1して更新
txt_number.value = str(int(txt_number.value) + 1)
page.update()
page.add(
ft.Row(
[
ft.IconButton(ft.icons.REMOVE, on_click=minus_click),
txt_number,
ft.IconButton(ft.icons.ADD, on_click=plus_click),
],
alignment=ft.MainAxisAlignment.CENTER,
)
)
ft.app(target=main)
コントロールの削除
✅popメソッドで削除できる。
例:一番上のコントロールを削除する
# 削除
page.controls.pop()
# 画面を更新
page.update()
カウンターアプリの場合
例として、プラスボタンを押したとき、プラスボタンを削除するようにしてみる。
import flet as ft
def main(page: ft.Page):
page.title = "Flet counter example"
page.vertical_alignment = ft.MainAxisAlignment.CENTER
txt_number = ft.TextField(value="0", text_align=ft.TextAlign.RIGHT, width=100)
def minus_click(e):
txt_number.value = str(int(txt_number.value) - 1)
page.update()
def plus_click(e):
txt_number.value = str(int(txt_number.value) + 1)
page.update()
# ✅プラスボタンを削除
page.controls[0].controls.pop(2) # controls[0]はRowのこと
# →controls[0].controlsにはマイナスボタン、テキストフィールド、プラスボタンの3つが入っている
# →→controls[0].controls.pop(2)はプラスボタンの削除を意味する
page.update()
page.add(
ft.Row(
[
ft.IconButton(ft.icons.REMOVE, on_click=minus_click),
txt_number,
ft.IconButton(ft.icons.ADD, on_click=plus_click),
],
alignment=ft.MainAxisAlignment.CENTER,
)
)
ft.app(target=main)
コントロールの種類
✅どんなコントロールがあるか?は公式ドキュメントを参照。
お手軽にそれっぽい画面を作る
✅画面を作るためのテンプレートが公式サイトにたくさん載っている。
公式のテンプレート:https://flet-controls-gallery.fly.dev/layout
コピペすれば使えるので、簡単にモダンな画面が作れる😊
例えばタブを作りたいときは……
画面を制御するためのプロパティ
画面を制御するために、コントロールにはさまざまなプロパティが用意されている。
イベントハンドラーon_〇〇
✅on_〇〇 = 任意の処理
でイベントハンドラーを設定できる。
ここでは代表的なイベントハンドラーon_〇〇
を3つ紹介する!
クリックイベントon_click
例:ボタンをクリックしたら「Click me」と表示する。
def button_clicked(e):
page.add(ft.Text("Clicked!"))
# ✅クリックしたときbutton_clickedを実行する
page.add(ft.ElevatedButton(text="Click me", on_click=button_clicked))
チェンジイベントon_change
例:チェックを付け外ししたとき「True」「Flase」の表示が切り替わる。
output_text = ft.Text()
def checkbox_changed(e):
output_text.value = (
f"チェックボックスの値 : {todo_check.value}."
)
page.update()
# ✅チェックを付け外ししたときcheckbox_changedを実行する
todo_check = ft.Checkbox(label="テスト", value=False, on_change=checkbox_changed)
page.add(todo_check, output_text)
ページ遷移イベントon_route_change
例:ページ遷移するとき目的のページ(テストページ)に遷移するよう設定する。
※ページ遷移の仕組みは後で解説する。
import flet
from flet import ElevatedButton, Page, Text, View
def main(page: Page):
# ページ遷移イベント
def route_change(e):
print("Route change:", e.route)
# ページクリア
page.views.clear()
# トップページ
page.views.append(
View(
"/",
[
ElevatedButton("テストページへ移動", on_click=open_test),
],
)
)
# テストページ
if page.route == "/test":
page.views.append(
View(
"/test",
[
Text("これはテストページです"),
],
)
)
# ページ更新
page.update()
# ✅ページ遷移イベントの登録
page.on_route_change = route_change
# テストページへ移動
def open_test(e):
page.go("/test")
page.go(page.route)
flet.app(target=main, view=flet.WEB_BROWSER)
その他のイベント
カウンターアプリの場合
「マイナスボタン」と「プラスボタン」にクリックイベントon_click
を設定している。
import flet as ft
def main(page: ft.Page):
page.title = "Flet counter example"
page.vertical_alignment = ft.MainAxisAlignment.CENTER
txt_number = ft.TextField(value="0", text_align=ft.TextAlign.RIGHT, width=100)
def minus_click(e):
txt_number.value = str(int(txt_number.value) - 1)
page.update()
def plus_click(e):
txt_number.value = str(int(txt_number.value) + 1)
page.update()
page.add(
ft.Row(
[
# ✅クリックしたとき「minus_click」を実行する
ft.IconButton(ft.icons.REMOVE, on_click=minus_click),
txt_number,
# ✅クリックしたとき「plus_click」を実行する
ft.IconButton(ft.icons.ADD, on_click=plus_click),
],
alignment=ft.MainAxisAlignment.CENTER,
)
)
ft.app(target=main)
コントロールの表示/非表示visible
✅visible = False
でコントロールが見えなくなる。
すべてのコントロールに表示/非表示の設定ができる。
# テキスト非表示(visible=False)
t = ft.Text(value="Hello, world!", color="green", visible=False)
page.add(t)
非表示にしたときの挙動
- 画面に表示されない
- フォーカスできない
- 選択できない
- イベントが発生しない
- 上記すべて、子要素にも適用される
コントロールの有効/無効disabled
✅disabled = True
でコントロールが触れなくなる。
すべてのコントロールに有効/無効の設定ができる。
# チェックボックス有効
check01 = ft.Checkbox( label="有効なチェックボックス", value=False )
page.add(check01)
# チェックボックス無効(disabled=True)
check02 = ft.Checkbox( label="無効なチェックボックス", value=False, disabled=True )
page.add(check02)
無効にしたときの挙動
- フォーカスできない
- 選択できない
- イベントが発生しない
- 上記すべて、子要素には適用されない
コントロールに任意の値を格納data
✅data
プロパティは自由にデータを格納してOK!
data
プロパティを設定できる。
汎用性が高くて便利!
data
は動作には影響しないので、何か値を残したいときはここに入れておくといい。
# テキストを生成
txt = ft.Text(value="Hello, world!")
# 任意の値を持たせておくことができる
txt.data = "hoge"
画面遷移
例:
トップページ
→ テストページ
→ トップページへ戻る
最終的なソースコード
hoge.py(任意のファイル名でOK)の1ファイルだけで作れる!
画面ごとにファイルを作るわけではない!
import flet
from flet import AppBar, ElevatedButton, Page, Text, View
def main(page: Page):
# ---------------------------------
# 関数定義
# ---------------------------------
# ページを更新する
def route_change(e):
print("Route change:", e.route)
# ページクリア
page.views.clear()
# トップページ(常にviewに追加する)
page.views.append(
View(
"/",
[
AppBar(title=Text("トップページ")),
ElevatedButton("テストページへ移動", on_click=open_test),
],
)
)
# テストページ(テストページのときだけviewに追加する)
if page.route == "/test":
page.views.append(
View(
"/test",
[
AppBar(title=Text("テストページ")),
Text("これはテストページです"),
],
)
)
# ページ更新
page.update()
# 現在のページを削除して、前のページに戻る
def view_pop(e):
print("View pop:", e.view)
page.views.pop()
top_view = page.views[-1]
page.go(top_view.route)
# テストページへ移動
def open_test(e):
page.go("/test")
# ---------------------------------
# イベントの登録
# ---------------------------------
# ページ遷移イベントが発生したら、ページを更新
page.on_route_change = route_change
# AppBarの戻るボタンクリック時、前のページへ戻る
page.on_view_pop = view_pop
# ---------------------------------
# 起動時の処理
# ---------------------------------
# ページ遷移を実行
page.go(page.route)
flet.app(target=main)
前提
- 複数のviewを使って画面遷移を実現する。
- 複数viewがあるときは、末尾のviewが画面に表示される。
-
view
は変数page
によって管理されている。
ページのクリア
# ページクリア
page.views.clear()
- ページ遷移したら毎回viewをクリアする。
- その後空っぽになったviewに、必要なviewを追加する。(この後の説明を参照)
トップページ
# トップページ(常にviewに追加する)
page.views.append(
View(
"/",
[
AppBar(title=Text("トップページ")),
ElevatedButton("テストページへ移動", on_click=open_test),
],
)
)
- viewが1つあるだけのシンプルな画面。
テストページ
# トップページ(常にviewに追加する)
page.views.append(
View(
"/",
[
AppBar(title=Text("トップページ")),
ElevatedButton("テストページへ移動", on_click=open_test),
],
)
)
# テストページ(テストページのときだけviewに追加する)
if page.route == "/test":
page.views.append(
View(
"/test",
[
AppBar(title=Text("テストページ")),
Text("これはテストページです"),
],
)
)
-
viewを2つ持っている。
- page.views[0] = トップページ(前のページ) 👈これは見えない
- page.views[1] = テストページ(今のページ) 👈一番末尾の要素が画面上に表示される
- これによって、AppBarに戻るボタンが表示される。(前の画面が分かる)
ページ遷移するたびにページをクリア(clear)してから、ページを追加(append)しているのがややこしい
❌「ページ遷移 = 遷移先のページを指定する」
⭕️「ページ遷移 = viewの配列を作る」
公式の解説:https://flet.dev/docs/guides/python/navigation-and-routing
Qiitaの解説:https://qiita.com/usagi_11/items/0ffcd7d209cf8a3733be
Qiitaの解説:https://qiita.com/donraq/items/b0cc1ad273996477b25a