Flet触ってみた

# Fletとは
https://flet.dev/

GoogleのFlutterをベースにしたPython のフレームワークで、
公式のイントロダクションに書かれていますが、フロントエンドの開発経験が無くてもイケてるUIを作ることが簡単にでき、作成したアプリがクールかつプロフェッショナルに見えることを助けてくれるそうです。

# 公式Docsは英語
TutorialsのToDoApp をなぞる形で実施していきます。
尚、公式のDocsは全て英語のため、私はChromeの拡張機能である「ほんやくコンニャク（[DeepL翻訳](https://chrome.google.com/webstore/detail/deepl-translate-reading-w/cofdbpoegempjloogbagkncekinflcnj?hl=ja)）」を使用しています。


#### 環境
macOS Big Sur 11.3.1
Python 3.10.2
flet 0.4.0

まずはFletのインポート
```
pip install flet
```
ハローワールド
```main.py
import flet as ft

def main(page: ft.Page):
    page.add(ft.Text(value="Hello, world!"))

ft.app(target=main)
```
わずかこれだけの記述ですがPython実行すると以下のようなウィンドウが立ち上がり、
「Hello, world!」というテキストが表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424984/3e415ac3-331b-fc46-471b-c3c48a3159af.png" width="400"> 

次にタスク名を入力するための TextField と、新しいタスクの Checkbox を表示するイベントハンドラを持つ 「+」ボタン（FloatingActionButton） を作成。
```main.py
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.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424984/e29fa456-3989-c2f2-0a96-9e1236d2426b.gif)

ほぼほぼToDoアプリっぽくなってますね
次は見栄えを整えます
```main.py
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)
```
「Row」   ページ上に水平にレイアウトするために使用
「Column」ページ上に垂直にレイアウトするために使用
コードを実行すると（画像は適当にToDoを入力して＋を押した後です）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424984/7bda5243-e176-1d1d-6465-527c1bcc9d40.png" width="400"> 
全体的に見た目が中心に寄せられていて見やすくなったかと思います

最後に再利用可能なコンポーネントを作るため、ステートとロジックを別のクラスでカプセル化

```main.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()

        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()

def main(page: ft.Page):
    page.title = "ToDo App"
    page.horizontal_alignment = ft.CrossAxisAlignment.CENTER
    page.update()
    # インスタンス作成
    todo = TodoApp()
    # アプリのルートコントロールをページに追加
    page.add(todo)

ft.app(target=main)
```
これは実行しても先ほどと同じ画面が出力されますが
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424984/7bda5243-e176-1d1d-6465-527c1bcc9d40.png" width="400"> 

上記コードの最後らへんを一部編集して実行してみる
```main.py
def main(page: ft.Page):
    page.title = "ToDo App"
    page.horizontal_alignment = ft.CrossAxisAlignment.CENTER
    page.update()
    # インスタンス作成
    todo1 = TodoApp()
    todo2 = TodoApp()
    # アプリのルートコントロールをページに追加
    page.add(todo1, todo2)
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424984/6143826e-b27d-b51c-c522-4312023b8921.png" width="400"> 

作ったTextFieldと「＋」ボタンのセットを１個のアイテムとして使い回し出来るようになりました。

# 所感
Flutterを全く触ったことのない僕でも、たった数行コードを書くだけでサクッとToDoアプリが作れちゃいました。
個人的には、好きなPythonを使ってフロントエンドっぽくあれやこれや出来るのが魅力です。
FletでGoogle検索してもトップ記事３番目あたりに「フレッツ光」が釣れることからも、まだまだ発展途上なことが伺えます。

# ひとりごと
コード部分は全てチュートリアルからのコピペです

おしまい

##### 参考ページ
https://qiita.com/NasuPanda/items/48849d7f925784d6b6a0