[Eel] Python, JavaScript/Reactでデスクトップアプリを作るには

 以前Eelを用いてPython, JavaScript/Vueでデスクトップアプリを作る方法を説明しました。

 今度はReactでどうやるかについて書いていきます。

Eelとは?


 Web技術を使ってPythonでGUIアプリを開発できるライブラリです。Electronに似た感じ。

https://github.com/samuelhwilliams/Eel

 ざっくりまとめるとこんな感じの仕組みです。

 内部的にはlocalhostにサーバーを立ててやり取りすることでWeb技術でGUIアプリが使えるという仕組みです。

 PythonとJavaScriptとの疎通は内部的にWebSocketを介して実現しています。

 Web技術が使えるので当然VueだったりjQueryだったりMaterializeも使用できます。

 PythonにはTkinterやKivyなどのGUIライブラリがありますが、EelはWeb技術を使えるのでそれらに比べて断然レイアウトを作りやすいのでおすすめです。

パッケージ構成


 Eelアプリのエンドポイントのrun.pyを起点とします。ここからアプリが立ち上がります。

 また、web配下にJavascript/html/Reactなどのコードを配置し、run.pyでアプリを起動するときにweb/buildのhtmlファイルなどを参照するようにします。

 publicは起点のhtmlであるindex.html、srcはjavascript/Reactなどのコードを配置します。

 それをビルドした結果のhtml, javascript, cssがbuildフォルダに生成され、Eel側ではbuildだけを参照してデスクトップアプリを動作させます。

まずはEelのセットアップ

 pipでEelをインストールします。

pip install eel

 次にエンドポイントのrun.py。とりあえずこれだけです。基本的にコメントの通りです。

import eel


def main():
    port = 10001  # 好きなポートで
    eel.init("./web/build")  # 使用するhtml/js/cssのあるフォルダを指定
    eel.start("index.html", port=port)  # 最初の画面index.htmlを指定

# @eel.expose()を指定してJavaScriptから呼べるように関数を登録
@eel.expose
def test_eel():
    print("from react.")


if __name__ == "__main__":
    main()

次にReactのセットアップ


 Reactはcreate-react-appでセットアップします。以下のコマンドを実行してください。

 事前にnpm, npxのインストールが必要なのでしておいてください。

npx create-react-app web

 これでrun.pyと同じ階層にReactアプリのwebディレクトリができます。

 試しにwebディレクトリに移動してnpm run startでreactアプリを立ち上げてみましょう。こんな感じのページが開くはずです。

 この時点では、Webページが立ち上がるため、Eelを用いたデスクトップアプリではありません。

Eelと連携


 Eelと連携する方法ですが、まずJavaScript側からEelを使えるようにするには<script>でeelをimportする必要があります。

 public/index.htmlのheadタグの中に以下の記載を追加します。ポート番号は先ほどrun.pyに指定したものと一致する必要があります。

<script src="http://localhost:10001/eel.js"></script>

 次にsrc/App.jsを以下のように修正しましょう。

...
function App() {
  const onClick = () => {
    window["eel"].test_eel()().then(() => {console.log("Eel関数呼び出し完了")})
  }
  return (
...
aタグを以下のように修正
        <a
          className="App-link"
          onClick={onClick}>
          Learn React
        </a>
...
}

export default App;

 リンクをクリックしたら、先ほどrun.pyに記載したPython側の処理(test_eel)を実行するように実装しています。

 関数の呼び方が特殊ですが、どうもこのようにしないと動かないようです。非同期だからPromiseになるのはわかるがなぜ()()にしなければいけないのか…。

React側のビルド


 ここまでで実装は一通り終わりました。

 今回のReactを用いたEelは先ほどのrun.pyに記載あるようにweb/buildを参照し、index.htmlが最初の画面になります。

 そのままではEelと連携して動かないのでビルドする必要があります。

 以下のコマンドでReact側のビルドができます。

npm run build

 web/build配下に色々ファイルができたと思います。

 さらに、面倒ですが、web/build/index.htmlの”/static~”となっているところを”./static~”にする必要があります。

 Eelと連携するためにファイルパスを合わせるためです。/staticのようにルートから参照だと、run.pyのディレクトリ/staticになるため、js/cssなどのファイルパスが合わないため画面が描画されなかったりします。

Eelデスクトップアプリの立ち上げ


 run.pyのディレクトリに戻って以下のpythonコマンドでアプリを立ち上げます。

python run.py

 先ほどと同じ画面が出て、赤線で囲ったリンクをクリックするとコンソールに”from react.”と表示されればPythonと連携ができていることになります。

 これでReact/html/Python(Eel)を用いたデスクトップアプリのサンプルが一通り作り終わりました!

課題


 このようにフロントエンド技術と連携できるし、TypeScriptなどももちろん導入できますが、仕組み的に

  1. フロント側のビルド
  2. /staticを./staticに書き換え
  3. run.py実行

をしないと動作確認できないのは結構大変です。

 なのでフロント側はコンポーネント分割してstorybookなどでレイアウトを確認して修正する、eelの処理のモックを作成するなどしないと効率がかなり悪いです。

 ただ、そのデメリットよりもWebフロントエンド技術でレイアウト作れるメリットの方が断然大きいと思います。

 数少ないEel関連の情報色々まとめているのでよかったら見てみてください!

https://deecode.net/?cat=41

コメントを残す

メールアドレスが公開されることはありません。