PythonでGUIアプリーケーションを作成する際はTkinterをこれまで使ってきたのですが、UIが少し古典的なところ(Custom Tkinterを使えば割とモダンなUIで作成も可能だが...)がイマイチ好きになれない理由でした。
最近はGUIアプリーケーションを作成できるPythonフレームワークのFletが注目されているみたいなので
この度、このブログでは珍しく旬なうちに触れてみました。
Flet環境構築
pipでfletをインストール
pip install flet
GUIでHello Worldを表示するコードを記述
import flet as ft
def main(page: ft.Page):
t = ft.Text(value="Hello, world!", color="red")
page.controls.append(t)
page.update()
ft.app(target=main)
pythonの実行
python hello_flet.py
Hello Worldを表示するだけのGUIアプリが立ち上がったかと思います。
環境構築動作手順はこんなもんでOKですね。
ちなみに、内部的にはWebアプリとして動作していますのでft.app(target=main)
の部分をft.app(target=main, view=ft.WEB_BROWSER, port=8550)
のようにポート指定で書き換えると
ブラウザからhttp://127.0.0.1://8550
でGUIアプリにアクセス可能です
Fletでログイン機能を作成
さて、本題です。Fletでログイン画面を作成してみます。
(今回はサクッと構築するため、データベースからの取得等は行わず、ハードコーディングのパスワード認証でログインを行います。)
ログインを行うためにはザックリと以下の処理を満たせれば良さそうです。
- IDとパスワードを入力するテキストボックス
- ログイン認証を行うためのログインボタン
- ログイン後ページ遷移 (ホーム画面遷移)
ログイン画面の作成
Fletのテキストボックスを作成するコードは以下になります。
ログイン画面っぽくするためログインIDとパスワードのテキストボックスを用意
import flet as ft
def main(page: ft.Page):
# ログインボタン押下ハンドラー
def login_button_clicked(e):
if login_check(login_id_field.value, password_field.value) is True:
login_text_field.value = "Loginに成功しました"
else:
login_text_field.value = "Loginに失敗しました。"
# ログインフィールド初期化
login_id_field.value = ""
password_field.value = ""
page.update()
# ログインID・パスワードチェック
def login_check(loginid, password):
ret = False
if loginid == "admin" and password == "password":
ret = True
return ret
# ログインIDフィールド
login_id_field = ft.TextField(hint_text="Login ID")
# 値の取得は login_id_field.value
# パスワードフィールド
password_field = ft.TextField(hint_text="PassWord", password=True)
# 値の取得は password_field.value
# ログインメッセージフィールド
login_text_field = ft.Text()
# ログインボタンフィールド
login_button_field = ft.FilledButton(
"Login",
style=ft.ButtonStyle(
shape=ft.RoundedRectangleBorder(radius=10),
),
on_click=login_button_clicked
)
page.add(login_id_field, password_field, login_text_field, login_button_field)
ft.app(target=main)
TextField()
でテキストボックスの作成が可能です。password=True
オプションでパスワード入力用のテキストボックスの作成が可能です。(入力文字を非表示にするアレ)
ボタンの種類はいろいろありますが、今回はFilledButton()
でログインボタンを作成しました。on_click
オプションでボタン押下時のイベントを設定できます。
今回はログインボタン押下時に入力パスワードのチェックを行い、ログイン結果をテキストメッセージ(Text()
)で表示しています。
ログインIDとパスワードはハードコーディングでコード内に埋め込んでいますので
Login ID: admin
Password: password
でログインが成功します。(「Loginに成功しました」というメッセージが表示されるだけ..)
ログイン成功時の画面遷移
Fletで画面遷移する処理を追加します。
ログインに成功したら画面遷移を行い、ログインに失敗したらログインエラーメッセージを表示する仕様とします。
import flet as ft
def main(page: ft.Page):
# ホーム画面のビュー作成
def create_home_view():
home_view = ft.View(
"/home",
[
ft.AppBar(title=ft.Text("Home"), bgcolor=ft.colors.BLUE),
ft.Text(value="Welcome to Home View"),
]
)
return home_view
# ルーティング
def route_change(handler):
troute = ft.TemplateRoute(handler.route)
if troute.match("/home"):
page.views.append(create_home_view())
page.update()
# ページを戻る際のルーティング
def back_page(handler):
page.views.pop() # 1つ前に戻る
top_view = page.views[-1]
page.go(top_view.route)
# ログインボタン押下ハンドラー
def login_button_clicked(e):
print(page.client_storage.get("number.setting"))
if login_check(login_id_field.value, password_field.value) is True:
page.go("/home")
login_text_field.value = ""
else:
login_text_field.value = "Loginに失敗しました。"
# ログインフィールド初期化
login_id_field.value = ""
password_field.value = ""
page.update()
# ログインID・パスワードチェック
def login_check(loginid, password):
ret = False
if loginid == "admin" and password == "password":
ret = True
return ret
# ルート変更時のロジック設定
page.on_route_change = route_change
# ログインIDフィールド
login_id_field = ft.TextField(hint_text="Login ID")
# 値の取得は login_id_field.value
# パスワードフィールド
password_field = ft.TextField(hint_text="PassWord", password=True)
# 値の取得は password_field.value
# ログインメッセージフィールド
login_text_field = ft.Text()
# ログインボタンフィールド
login_button_field = ft.FilledButton(
"Login",
style=ft.ButtonStyle(
shape=ft.RoundedRectangleBorder(radius=10),
),
on_click=login_button_clicked
)
# ページを戻る時のロジック設定
page.on_view_pop = back_page
page.add(login_id_field, password_field, login_text_field, login_button_field)
if __name__ == "__main__":
ft.app(target=main)
下記でルーティングの設定を行っています。route_change()
ハンドラにはルーティングのパス定義を行います。back_page()
ハンドラには画面の戻るボタンを押した際の挙動を記述します。
# ルーティングの設定
page.on_route_change = route_change
:
# ページを戻る際に行うアクションを定義 (前の画面へ戻る)
page.on_view_pop = back_page
ページ遷移はpage.go()
で行えます。
ログインに成功したら/home
へ遷移するために呼び出しています。
# /homeへ遷移する場合
page.go("/home")
ここまで実装すると先程のログイン画面からログインに成功すると下記の画面(ホーム画面)へ遷移することができます。
画面上部の「戻る」ボタンを押すとログイン画面へ戻れるところまで確認しました。
ログイン処理はしっかり作り込みたい
ログイン処理はハードコーディングでしたが、なんとか一応Fletでログイン機能の実装まで行えました。
ログインIDとパスワードはDB管理しておきログイン時にDBアクセスする仕様の方がかっこいいですね。
(時間のあるときに実装して記事更新しておきます..)
コメント