まんま!の備忘録

ソフトウェア・ファームウェア・ハードウェア関連の備忘録

Flet を使用したGUIアプリ開発 (Mac / Raspberry Pi)

最近Google のトップ画面にニュースや興味ありそうな記事が表示されるようになりましたね。
わりと興味ある分野が表示されているので、その辺のサイトにあるような広告よりクリックしちゃいがちです。


今日、Fletについてまとめている記事があったので、それを自分もやってみようかと。
流れは、Mac Bookで画面構築した後、ラズパイにコピーして実行という形にします。
(ラズパイにリモート接続して、そこで開発でもいいのですが、持ってるのがRaspberry Pi Zero WHと3B+なので。
 3B+はVisual Studio Codeでリモート開発もできるのですが、たまに固まる。スペック足らんのかね。
 Zero WHはそもそもVisual Studio Codeでリモート開発ができない。)

とりあえず以下に、手順記載していきます。

Macで開発

1. 作業ディレクトリ作成
私は、Githubリポジトリ作ってみたので以下のように進めます。ここは各々で。

$ cd develop/raspberrypi/projects
$ git clone https://github.com/taogya/FletSample.git
$ cd FletSample

2. 開発環境構築
venv使用して、仮想環境作ります。ここも各々で。

$ python3.9 -m venv venv
$ . venv/bin/activate

次に、Visual Studio Codeでの開発環境を準備します。
これは以下参照。
taogya.hatenablog.com

ライブラリインストールします。

$ pip install flet autopep8 isort flake8
$ pip freeze > requirements.txt

3. サンプル作成
CPU温度を取得してそれをチャートに表示します。
クリアボタンをクリックで、チャートをクリアします。
そんなサンプルです。

ファイル作成します。コマンドで書いてますが、Visual Studio Code上でやってもらってOKです。

$ mkdir src
$ cd src
$ touch main.py

まずは Flet app example のコードそのままコピペして実行してみます。
flet.dev

$ python main.py


OKですね。では本番。

import os
import threading
import time

import flet as ft


def main(page: ft.Page):
    # タイトルの設定
    page.title = 'Flet Sample'
    # ページの配置を中央に設定
    page.vertical_alignment = ft.MainAxisAlignment.CENTER

    # チャートに表示するデータ
    data_points = [
    ]
    # チャートに表示するシリーズの設定
    data_series = [
        ft.LineChartData(
            data_points=data_points,
            stroke_width=5,
            color=ft.colors.CYAN,
            curved=True,
            stroke_cap_round=True,
        )
    ]
    # チャートの設定
    chart = ft.LineChart(
        data_series=data_series,
        border=ft.border.all(3, ft.colors.with_opacity(0.2, ft.colors.ON_SURFACE)),
        horizontal_grid_lines=ft.ChartGridLines(
            interval=1, color=ft.colors.with_opacity(0.2, ft.colors.ON_SURFACE), width=1
        ),
        vertical_grid_lines=ft.ChartGridLines(
            interval=1, color=ft.colors.with_opacity(0.2, ft.colors.ON_SURFACE), width=1
        ),
        left_axis=ft.ChartAxis(
            labels_size=48,
        ),
        bottom_axis=ft.ChartAxis(
            labels_size=32,
        ),
        tooltip_bgcolor=ft.colors.with_opacity(0.8, ft.colors.BLUE_GREY),
        min_y=0,
        max_y=100,
        expand=True,
    )

    # チャートをクリアする
    def clear_chart(e):
        data_points.clear()
        chart.update()

    # ページにコンポーネントを追加
    page.add(
        ft.Row(
            controls=[
                chart,
            ],
            expand=True,
            alignment=ft.MainAxisAlignment.CENTER,
        ),
        ft.Row(
            controls=[
                ft.FilledButton(text='Clear', on_click=clear_chart, expand=True),
            ],
            alignment=ft.MainAxisAlignment.CENTER,
        )
    )

    # 温度を取得する
    def get_temperature():
        try:
            temp = os.popen('vcgencmd measure_temp').readline()
            temperature = float(temp.replace('temp=', '').replace('\'C\n', ''))
            return temperature
        except BaseException:
            # エラーが発生した場合はランダムな値を返す
            import random
            return random.randint(0, 40)

    # チャートを更新する
    def update_chart():
        while True:
            data_points.append(ft.LineChartDataPoint(x=len(data_points), y=get_temperature()))
            chart.update()
            time.sleep(1)

    # チャートを更新するスレッドを開始
    th = threading.Thread(target=update_chart)
    th.start()


if __name__ == '__main__':
    from argparse import ArgumentParser

    # コマンドライン引数のパース
    parser = ArgumentParser()
    parser.add_argument('--host', type=str, default=None)
    parser.add_argument('--port', type=int, default=0)
    args = parser.parse_args()

    # アプリのビューを設定(host が指定されている場合はブラウザで開く)
    view = ft.AppView.FLET_APP if not args.host else ft.AppView.WEB_BROWSER

    # アプリの起動
    ft.app(target=main, host=args.host, port=args.port, view=view)

GUIアプリとして実行

$ python main.py

WEBアプリとして実行

$ python main.py --host 0.0.0.0 --port 8080

http://localhost:8080

Raspberry Pi

CUI環境で使用しているので、WEBアプリとして起動するようにします。
Macと同様に進めます。
1. 作業ディレクトリ作成

$ cd work
$ git clone https://github.com/taogya/FletSample.git
$ cd FletSample

2. 開発環境構築

$ python3.9 -m venv venv
$ . venv/bin/activate
$ pip install -r requirements.txt

3. 実行

$ ifconfig | grep inet | cut -d: -f2 | awk '{ print $2}' | grep -vE "^(127\..*|172\..*|\s*)$"
192.168.0.20
$ python main.py --host 0.0.0.0 --port 8080

http://192.168.0.20:8080