Pythonで作るGUIアプリFletでログイン機能を作成してみる

  • URLをコピーしました!

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ですね。

flet画面

ちなみに、内部的には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())で表示しています。

flet_ログイン画面

ログイン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_ホーム画面

画面上部の「戻る」ボタンを押すとログイン画面へ戻れるところまで確認しました。

ログイン処理はしっかり作り込みたい

ログイン処理はハードコーディングでしたが、なんとか一応Fletでログイン機能の実装まで行えました。

ログインIDとパスワードはDB管理しておきログイン時にDBアクセスする仕様の方がかっこいいですね。
(時間のあるときに実装して記事更新しておきます..)

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次