見出し画像

Flet チュートリアル(Todoアプリ①)

前回Fletとはそもそも何かと、サンプルでじゃんけんゲームを作成しました。

そもそもちゃんとドキュメントすら読んでなかったので、公式サイトにあるチュートリアルに沿って学んでいきたいと思います。

結構初めの頃ってチュートリアル読んでも、それ自体が呪文にしか思えなくて、萎えてしまうことが多かったので読んでもよく分からんという方は参考にしてみていただけたら幸いです。

なお、公式ページのギャラリーには完成品もあるので、まずはそちらを触ってみます。

1. 公式ページのギャラリーで完成品を試す

(1) TODOの追加

「What needs to be done ?」と表示されているエリアを選択すると、テキストが入力できるので、適当に入力して「+」ボタンを押下します。

TODO事項(やること その①)を入力

すると、下側にあるエリアに入力したTODO事項がチェックボックス付きで表示されました。

追加されたTODO事項は編集・削除が可能

(2) タブの切り替え表示を確認する

all・active・completeというタブがあるので、これを試してみるために2個目のTODO事項を入力して、チェックボックスにチェックを入れてみます。

2個目のTODO事項を登録
1個目にチェックを入れるとallタブには2つ表示される
activeタブでは2つ目のみが表示
completedタブでは1つ目のみが表示

(3) 登録したTODOの編集・削除

次に、登録済のTODOを編集してみます。「やること その①」の右横にあるペンのようなアイコンをクリックする。

テキストが編集可能となるので、後ろに「_修正」と加えて、緑のチェックボタンを押下します。

ペンのアイコンでアクティブとなったテキストを修正し、緑のチェックボタンを押下
TODO内容が更新された

次に、「やること その②」の横にある、ペンアイコンの更に右のゴミ箱アイコンを押してみます。

TODOが削除された

なお、一番右下にある「Clear competed」ボタンを押下したら、全てTODOが消えました。

2.チュートリアル通り試してみる

では、順を追ってチュートリアル通りにコードを書いて、実行していきます。

(1) テキストフィールド・追加ボタンを用意

出だしのHello World!!は割愛します。
チュートリアルに記載されているコードは、以下の通り。

import flet as ft  #①

def main(page: ft.Page): #②
    def add_clicked(e): #③
        page.add(ft.Checkbox(label=new_task.value))
        new_task.value = ""
        page.update()

    new_task = ft.TextField(hint_text="Whats needs to be done?") #④

    page.add(new_task, ft.FloatingActionButton(icon=ft.icons.ADD, on_click=add_clicked)) #⑤

ft.app(target=main) #⑥

(2) 各行の記述の意味を理解する

①はfletのインポートと、PGM内ではfletをftとして記載するよという宣言。

②はmain関数に引数として、ft.Pageをpageとして渡しています。

③は後述⑤で追加ボタンの押下をキックに、チェックボックスを追加するためのadd_clickedという関数を定義しています。
ちなみに、チェックボックスにlabelとして、new_task.valueを渡していて、初期値を""(ブランク)更新するようになっています。

その上で、④ではnew_taskにはテキストフィールドを格納し、更にhint_textとして"Whats needs to be done?"を渡すようにしています。

少しわかりづらいかもしれませんが、ボタン押下時にチェックボックスと、new_taskというテキストフィールドに入力された値をページに追加し、new_taskの値を初期化することで入力欄を元に戻しているイメージです。

試しに、「new_task.value=""」の部分を消してみましょう。

import flet as ft

def main(page: ft.Page):
    def add_clicked(e):
        page.add(ft.Checkbox(label=new_task.value))
        #new_task.value = ""    行をコメントアウトする
        page.update()

    new_task = ft.TextField(hint_text="Whats needs to be done?")

    page.add(new_task, ft.FloatingActionButton(icon=ft.icons.ADD, on_click=add_clicked))

ft.app(target=main)

そして、ターミナルやコマンドプロンプトでプログラムを起動します。
(私はtodo_study.pyというファイル名なので、以下のように起動しました)

python todo_study.py

こんな感じで立ち上がると思います。

上部に入力欄、下部に追加ボタン

では、試しに「テスト」と入力して追加ボタンを押してみましょう。

入力欄に「テスト」という文字が残る

今度は、コメントアウトしていた「new_task.value=""」の行を元に戻して再度同じオペレーションをしてみましょう。

TODOが追加されるとともに、入力欄がhint_textに戻った

こんな感じで、一部改変して実験するとそのコードが何のために書かれているのかが、より理解しやすくなったりするかと思います。

⑤でnew_task(テキストフィールド)と、add_clicked関数をon_click処理として渡したFloatingActionButtonをpageに追加しています。

⑥でmain関数を引数targetとして、appメソッドを実行しています。

3.レイアウトを整える

すでに2.まででもTODOアプリの最低限の機能は充足していますが、チュートリアルでは「Page layout」というタイトルでレイアウトのデザインの仕方について例示がされています。

(1) 画面レイアウトを把握する

はじめに、画面レイアウトが示されていますね。

公式ページ(https://flet.dev/docs/tutorials/python-todo/)より

行(Row)として、入力欄(テキストフィールド)と追加ボタン(FloatingActionButton)がまず置かれています。
※入力欄のExpand引数はTrueだとあります。

そしてその下には、task_viewというColumn(列)として、複数のCheckboxが縦に並ぶリストが配置されています。

更に、ViewというColumnに、前述のRowとtask_viewというColumnが配置されているという構造です。

少し分かりづらいかもしれませんが、以下のようなイメージです。

逆に分かりづらかったらすいません・・・

(2) コードを実行してみる

公式ページにあるコードのまま、プログラムを実行してみましょう。
以下がコードです。

import flet as ft


def main(page: ft.Page):
    def add_clicked(e):
        tasks_view.controls.append(ft.Checkbox(label=new_task.value))
        new_task.value = ""
        view.update()

    new_task = ft.TextField(hint_text="Whats needs to be done?", expand=True) #①
    tasks_view = ft.Column() #②
    view=ft.Column(
        width=600,
        controls=[
            ft.Row(
                controls=[
                    new_task,
                    ft.FloatingActionButton(icon=ft.icons.ADD, on_click=add_clicked),
                ],
            ),
            tasks_view,
        ],
    ) #③

    page.horizontal_alignment = ft.CrossAxisAlignment.CENTER #④
    page.add(view) #⑤

ft.app(target=main)

私は、todo_study_2.pyというファイル名で保存しているので、再び以下のように実行します。

python todo_study_2.py

すると、以下のように表示されます。

少しレイアウトが整いました
todoを入力してみました

4.作成したUIやメソッドをクラスとして定義する

長くなってきたので、最後にUIやメソッドをクラスにするところまでやってみます。(todo_study_3.pyというファイル名で作成)

import flet as ft

class TodoApp(ft.UserControl):
    def build(self):
        self.new_task = ft.TextField(hint_text="Whats needs to be done?", expand=True)
        self.tasks = ft.Column()

        # application's root control (i.e. "view") containing all other controls
        return ft.Column(
            width=600,
            controls=[
                ft.Row(
                    controls=[
                        self.new_task,
                        ft.FloatingActionButton(icon=ft.icons.ADD, on_click=self.add_clicked),
                    ],
                ),
                self.tasks,
            ],
        )

    def add_clicked(self, e):
        self.tasks.controls.append(ft.Checkbox(label=self.new_task.value))
        self.new_task.value = ""
        self.update()

※クラスって何?という方はこちら・・・

そして、作成したクラスを再利用するプログラムを別に作ります。
(todo_study_4.pyというファイル名で作成)

import flet as ft
from todo_study_3 import TodoApp

def main(page: ft.Page):
    app1 = TodoApp()
    app2 = TodoApp()
    app3 = TodoApp()

    page.add(app1, app2, app3)

ft.app(target=main)

先ほど作成したtodo_study_3.pyファイルから、TodoAppクラスをインポートしています。
そして、app1、app2、app3という変数にそれぞれ、TodoAppクラスを格納して、addメソッドでpageに追加しています。

立ち上がったUIを確認してみましょう。

1画面にTodoAppが3つ表示されました

そして、それぞれtodo事項を追加する

それぞれtodo事項が追加できました

では、次回もドュメントを見ながら、色々試してみましょう。
ご自分でも是非、一部コードを変えたりして実行してみてください。


この記事が気に入ったらサポートをしてみませんか?