見出し画像

FletでPythonベースのGUIを作成する

今日は、たまたま知って興味をそそられた「Flet」について、ご紹介したいと思います。「Flet」とは、「Flutter」で構築されたモバイルアプリ・Webアプリのフレームワークです。
そして、ここがポイントですがPythonで記述することができます。

つまり、Pythonがある程度理解できていれば、HTMLやCSS、JavaScriptなどのフロントエンドの言語は使わないでOKということかと思います。

まず、この記事ではFletの概要と、手っ取り早く実行環境の構築、サンプルコードの実行と改変によるとっかかり部分を記載したいと思います。

1.Fletってなんでしょうか

 まずはそこですよね。「Flutter」とは何ですかっていうと・・・、Google社が開発したiOSとAndroidのモバイルアプリ、Webアプリも作成できるフレームワークです。

DartというこれまたGoogle社が、JavaScriptの代替言語として開発したプログラミング言語で、Widgetと呼ばれるボタンやテキストラベルなどを組み合わせてGUI(グラフィカルユーザーインターフェース)を作成することができます。

一度、自分もFlutterをかじってみたのですが、ちょっと自分にはDartの学習コストが余計に感じられてしまい早々にリタイアしてしまいました。

2.Fletに魅力を感じた理由

 何より、DartでなくPythonベースで作成できるという部分が興味をそそられた部分です。

過去、TkinterでのGUI作成の記事を書いていますが、それなりにTkinterも学習コストがあるのと、いかんせんあまり美しくないのと。
そこそこ、あちこち調べながらコードを書いていく必要があります。
(私がしょぼいのでしょうが、結構時間かかる・・・)

【ご参考】

3.開発環境を構築(インストールだけ)する

 何はともあれ、まずは実行あれ。Fletの公式ページに掲載されているコード例を実行してみたいと思います。

なお、FletはPythonの外部ライブラリなので、fletをインストールする必要があります。pipを使って実行するか、Anacondaを利用されてる方はcondaコマンドでインストールするか。

WindowもMacもありますが、今回はMacを使ってやってみたいと思います。
miniforgeでPythonを利用しているため、Conda insallで行きます。

【ご参考】miniforgeをM1 macにインストールする方法

まず、flet学習用の仮想環境を構築します。

conda create -n 仮想環境名 

下が、実際のターミナル画面ですが、続行(Proceed)する?って聞かれて「y」で実行できます。
画面下部あたりに出てきた通り、conda activate 環境名で仮想環境をアクティブに、conda deactivateで非アクティブにできます。

仮想環境を作成する

次に先ほど作成した仮想環境をアクティベートしたうえで、外部ライブラリであるFletをインストールします。

conda activate 仮想環境名
conda install flet

以下が実際のターミナル画面の画像です。

1・2行目がコマンド入力した内容です

さらに、Fletのインストールによりダウンロードされるパッケージと、以下はすでにインストールされてるよってものが表示され、再び続行するか?
と聞かれるので、「y」と入力します。

ダウンロードされました。

4.Fletのサンプルコードを動かしてみる

 では環境構築ができたので、実際にFletのサンプルコードを動かしてみましょう。

Fletの公式ページにある、サンプルコードを流用した上で、少し改変して実験してみましょう。

以下が公式ページに乗っているサンプルコードです。

import flet as ft  #①部分

def main(page: ft.Page): #②部分
    page.title = "Flet counter example"
    page.vertical_alignment = ft.MainAxisAlignment.CENTER

    txt_number = ft.TextField(value="0", text_align=ft.TextAlign.RIGHT, width=100) #③

    def minus_click(e): #③部分
        txt_number.value = str(int(txt_number.value) - 1)
        page.update()

    def plus_click(e): #③部分
        txt_number.value = str(int(txt_number.value) + 1)
        page.update()

    page.add(
        ft.Row(
            [
                ft.IconButton(ft.icons.REMOVE, on_click=minus_click),
                txt_number,
                ft.IconButton(ft.icons.ADD, on_click=plus_click),
            ],
            alignment=ft.MainAxisAlignment.CENTER,
        )
    ) #④部分

ft.app(target=main) #②部分

とりあえず、そのまま公式ページのサンプルコードをコピーして拡張子を.pyとして自分のPC内の何処かにcounter.pyとして保存しましょう。

私は、documentsフォルダにflet_studyフォルダを作成したのでそこに格納します。

それでは、ターミナル上でプログラムを格納したフォルダにcd(チェンジディレクトリ)コマンドで移動し、プログラムを実行してみましょう。

cd パイソンファイルを格納したフォルダ
python counter.py

以下が実行した際のターミナルの画像です。

フォルダ移動して、Pythonファイルを実行する

すると、こんなウインドウが立ち上がると思います。

counter.pyを実施すると表示されるウインドウ

マイナスボタンを押すと表示されている数字が1減算され、プラスボタンを押すと数字が1加算される。GUIがシンプルなコードで作成できるのが分かります。

5.サンプルコードの中身

ドキュメントをまだ全く読んでないので、完全に見た感じで何がどう聞いているのか確認してみます。テキトーでごめんなさい。。。

① fletのインポート

flet関数をインポートして、ftという名前で呼び出せるようにしています。

import flet as ft

② GUIのレイアウト

main関数の引数にpageとして、Pageクラスを設定。
page.titlegがウインドウタイトル、page.vertical_alignmentで表示位置をセンターに設定。

後述の③で処理や部品を定義し、一番最後にあるapp関数でメイン関数で定義した処理を実行させている感じの構成と思われます。
(アウトラインは以下のイメージ)

def main(page: ft.Page):
   page.title = "ウインドウタイトル"
   page.vertical_alignment = ft.MainAxisAlignment.表示方法
   
      #・・・パーツやら処理やらの定義・・・
      
   page.add(#パーツに定義した処理含めて、pageオブジェクトに追加する)

ft.app(target = main)

すごく感覚的に分かりやすい構成ですね。

③ オブジェクト・処理の定義

まず、表示させるアウトプットである数字を、文字列を表示するオブジェクト(TextField)として、text_numberという変数に格納します。
(引数で値やら、テキストの表示位置、幅などを定義)

txt_number = ft.TextField(value="0", text_align=ft.TextAlign.RIGHT, width = 100)

そして、後ほど出てくるマイナスボタンとプラスボタンを押した場合の関数を定義しています。
なお、おそらく関数の引数「e」はイベント発生時に処理される関数を定義する際に設定するもので、update関数は処理が行われた際に画面を更新するものと思われます(読めよ・・・ドキュメント)

#マイナスボタンにあてがわれる処理
def minus_click(e):
   txt.number.value = str(int(txt_number.value) - 1)
   page.update()

#プラスボタンにあてがわれる処理
def plus_click(e):
   txt.number.value = str(int(txt_number.value) + 1)
   page.update()

④ 画面にオブジェクトを並べる

そして、page.addメソッドに引数として、引数でリスト形式で表示するオブジェクトを渡したRow関数を渡して、これを横並びで画面には表示させてねセンター寄せで、って感じの定義をしていますね。(適当過ぎません?)

マイナスのアイコン、数値、プラスのアイコンと、リストに格納した順に横並びで画面に表示されるようです。

    page.add(
        ft.Row(
            [
                ft.IconButton(ft.icons.REMOVE, on_click=minus_click),
                txt_number,
                ft.IconButton(ft.icons.ADD, on_click=plus_click),
            ],
            alignment=ft.MainAxisAlignment.CENTER,
        )
    )

6.少しコードを改変して実験してみる

 何でも実際にコードを動かしながら、出たエラーを修正していくと覚えるのが早いと思います。

そこで、これをベースに少し改変してじゃんけんゲームを作ってみようと思います。

正直テキストを単純に表示したい場合とか、アイコン以外のボタンの表示の仕方とかは流石に分からなかったので、ここまで来てちょっとドキュメントを読みました 笑

実行してみると・・・

一応画面表示はされた

実際に下にある、グーボタンを試しに押してみると・・・

処理も機能していることを確認

・・・なーんて、サラッと上手くいったように書いてますが、実際は実行の度に出るエラーを潰しまくってやっと完成した感じです。
デザイン性皆無ですが 笑

コードが知りたい方はこちらです↓
なお、リスタートボタンを作ってないので、ぜひ自分で追加してみてください。

ここから先は

2,628字

¥ 300

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