なぜFletがPython GUI開発のゲームチェンジャーなのか
長年、Python開発者は難しい選択を迫られてきました。Windows 95時代の遺物のような見た目のTkinterを使うか、学習曲線の非常に険しいPyQtと格闘するかです。モダンな外観を求める場合はElectronに移行するのが一般的でしたが、Electronは重いChromiumインスタンスを管理し、JavaScriptを書く必要があるため、単純なアプリでも待機時に200MB以上のメモリを消費することがよくあります。
Fletはこの状況を打破する架け橋となります. GoogleのFlutterエンジンを利用することで、Dartを一行も書かずにプロフェッショナル級のインターフェースを構築できます。ロジックは純粋なPythonで書き、レンダリングはFletが担当します。私は社内の監視ツールとしてFletを本番環境で運用していますが、特にスピードが求められるデータ量の多いダッシュボードにおいて、驚くほど安定しています。
競合フレームワークとの比較
新しいプロジェクトを始める際、私は通常3つの主要な選択肢を検討します。
- Electron: UIは美しいが、リソースを大量に消費する。PythonバックエンドにWebスタック(HTML/CSS/JS)が加わるため、開発が複雑になる。
- PyQt/PySide: 成熟しておりネイティブに近いが、スタイリングが苦行。QSS(Qt Style Sheets)は実質的にCSSの制限された不自由なバージョンである。また、商用ライセンスは開発者一人につき500ドル以上かかる場合がある。
- Flet: Flutterの宣言型モデルを採用。プロトタイピングが非常に速く、一つのコードベースでデスクトップ、Web、モバイルに対応. 何よりApache 2.0ライセンス(無料)である。
正直な評価:メリットとデメリット
完璧なツールなど存在しません。DevOpsダッシュボードの構築にFletを6ヶ月間使用して分かった、このフレームワークの現実を伝えます。
メリット
- CSSのストレスがゼロ:
Row、Column、ContainerといったPythonのクラスを使ってレイアウトを構築します。フロントエンドの専門家ではない開発者にとって、これは大きな解放感です。 - 即座にWeb展開可能: コマンド一つでデスクトップアプリをWebアプリに変換できます。社内ツールをURL経由で共有するのに最適です。
- リアクティブな状態管理: UIの更新が直感的です。プロパティを変更し、
page.update()を呼び出すだけで完了します。 - 軽快なイテレーション: ホットリロードは従来のライブラリよりもはるかに速く感じられます。変更はミリ秒単位で反映されます。
デメリット
- 初期のバイナリサイズ: FletはFlutterエンジンを同梱するため、”Hello World”の実行ファイルでも約60MBからになります。小さなユーティリティツールとしては少し重めです。
- プラットフォームの制約: Flutterが提供するウィジェットに制限されます。プロジェクトが低レベルのOSフックや非常に特殊なハードウェア操作を必要とする場合は、依然としてPyQtの方が安全な選択です。
環境のセットアップ
システムを汚さないために、仮想環境の使用をお勧めします。FletにはPython 3.7以降が必要です。セットアップは2分もかかりません。
# 仮想環境を作成して有効化
python -m venv venv
source venv/bin/activate # Windowsの場合: .\venv\Scripts\activate
# ライブラリをインストール
pip install flet
また、VS Code用のFlet拡張機能の導入も推奨します。定型コードの繰り返し入力を省けるスニペットが用意されています。
実用的なシステムモニターの構築
実際に役立つものを作ってみましょう。CPUとメモリの使用率を表示するライブダッシュボードです。この例では、Fletがリアルタイムデータとスタイリングをどのように処理するかを示します。
import flet as ft
import psutil
import threading
import time
def main(page: ft.Page):
page.title = "システムモニター Pro"
page.theme_mode = ft.ThemeMode.DARK
page.window_width, page.window_height = 400, 450
# UIコンポーネントの定義
cpu_text = ft.Text("CPU: 0%", size=20, weight="bold")
ram_text = ft.Text("メモリ: 0%", size=20, weight="bold")
cpu_bar = ft.ProgressBar(width=300, color="blue")
ram_bar = ft.ProgressBar(width=300, color="green")
def refresh_stats():
while True:
cpu = psutil.cpu_percent()
ram = psutil.virtual_memory().percent
cpu_text.value, cpu_bar.value = f"CPU: {cpu}%", cpu / 100
ram_text.value, ram_bar.value = f"メモリ: {ram}%", ram / 100
page.update()
time.sleep(1)
page.add(
ft.Column([
ft.Icon(name=ft.icons.DASHBOARD, size=50, color="blue"),
ft.Text("パフォーマンス", size=28, weight="bold"),
ft.Divider(),
cpu_text, cpu_bar,
ft.Container(height=10),
ram_text, ram_bar,
], horizontal_alignment="center")
)
threading.Thread(target=refresh_stats, daemon=True).start()
ft.app(target=main)
コードの解説
pageオブジェクトがウィンドウに相当します。WebデザインのFlexboxのように、ft.Columnを使って要素を垂直に積み上げます。ロジックはシンプルです。バックグラウンドスレッドがpsutil経由でデータを取得し、オブジェクトのプロパティを更新してpage.update()をトリガーします。クリーンで読みやすく、古いフレームワークに見られる「コールバック地獄」を回避できます。
マルチページ・ナビゲーション
アプリが1画面だけで完結することは稀です。FletはURLスタイルのルーティングシステムを採用しており、Webブラウジングのような感覚で画面遷移を行えます。複数のビューを持つツールの構造例は以下の通りです。
def main(page: ft.Page):
def route_change(e):
page.views.clear()
page.views.append(
ft.View("/", [
ft.AppBar(title=ft.Text("ホーム")),
ft.ElevatedButton("設定へ", on_click=lambda _: page.go("/settings"))
])
)
if page.route == "/settings":
page.views.append(
ft.View("/settings", [
ft.AppBar(title=ft.Text("設定")),
ft.ElevatedButton("戻る", on_click=lambda _: page.go("/"))
])
)
page.update()
page.on_route_change = route_change
page.go("/")
このパターンを使えば、プロジェクトが大きくなってもコードを整理された状態に保てます。私は、設定編集とログのストリーミング用に別々のビューが必要なデプロイツールで、まさにこの構造を使用しています。
パッケージ化と配布
アプリを共有する準備ができたら、ユーザーにPythonのインストールを求めるのは避けたいものです。Fletならパッケージ化も簡単です。まず、ビルドツールをインストールします。
pip install flet[all]
Windowsのスタンドアロンアプリを作成するには、以下を実行します。
flet build windows
これにより、build/windowsフォルダに実行ファイルが生成されます。ビルドは対象となるOS上で行う必要があることに注意してください。macOS用の.appバンドルを作成するには、Mac上でこのコマンドを実行する必要があります。
最後に
スクリプトからGUIアプリへの移行は、あらゆるITエンジニアにとって大きな前進です。Fletはそのハードルを大幅に下げてくれます。本番レベルの社内ソフトウェアに耐えうる安定性があり、十分に検証されたエンジン(Flutter)の恩恵を受けられます。新しいWebスタックを学ばずに、デフォルトでダークモードに対応したプロフェッショナルな外観のツールが必要なら、FletはPython開発者にとって最も効率的な選択肢となるでしょう。

