概要
Python でブラウザベースの GUI アプリケーションを作成できるライブラリ Eel について解説します。
Eel
Eel は、Electron のようなオフラインの HTML、Javascript を使用した GUI アプリケーションを作るための Python ライブラリです。機械学習や画像処理など Python が得意な部分とモダンな GUI を作成できる HTML、Javascript の得意な部分を組み合わせたアプリケーションが作成できます。
他の GUI ライブラリとの比較
Python で GUI アプリケーションを作成するためのライブラリで有名なものでは、tkinter、PySimple GUI、PyQt があります。これらはいずれも OS が提供するネイティブの UI コンポーネントを使用してライブラリを作成するライブラリです。ネイティブ UI は、テキストボックスやプルダウンメニューといった GUI に必要な部品は一通り提供されていますが、カスタマイズできるデザインの幅は少なく、画一的な見た目になります。一方、Eel はブラウザベースであるため、GUI を得意とする HTML、Javascript の資産を活用して、凝った見た目の UI を簡単に作ることができるというメリットがあります。
インストール
Eel をインストールします。
pip install eel
基本的な使い方
eel_templates/eel_basic に以下の手順で作成したテンプレートファイルがあります。
1. プロジェクトディレクトリを作成する
適当なディレクトリに以下のディレクトリ構成で .py ファイルと .html ファイルを作成します。
<ProjectName>
├── app.py <-- Python スクリプト
└── web
└── hello.html <-- HTML ファイル
2. .html ファイルを編集する
web/index.html
ファイルを作成します。.html ファイルには、<script type="text/javascript" src="/eel.js"></script>
が挿入されている必要があります。eel.js
自体は web ディレクトリに存在しませんが、それで問題ありません。
<!DOCTYPE html>
<html>
<head>
<title>Hello, World!</title>
<!-- Include eel.js - note this file doesn't exist in the 'web' directory -->
<script type="text/javascript" src="/eel.js"></script>
</head>
<body>
Hello, World!
</body>
</html>
3. .py ファイルを編集する
import eel
def main():
eel.init("web")
eel.start("index.html", size=(1024, 768), port=8080)
if __name__ == "__main__":
main()
4. 起動する
app.py
を実行すると、GUI 画面が表示されます。
python app.py
Javascript の関数を Python から呼び出す
引数がない関数
Javascript の関数を Python から利用したい場合は、eel.expose(<関数名>);
を呼び出したい関数の先頭につけます。Python 側からは eel.<関数名>(<引数一覧>)
で呼び出せます。関数は非同期で実行されます。
<!DOCTYPE html>
<html>
<head>
<title>Hello, World!</title>
<!-- Include eel.js - note this file doesn't exist in the 'web' directory -->
<script type="text/javascript" src="/eel.js"></script>
<script>
eel.expose(echo);
function echo(msg) {
console.log(msg);
}
</script>
</head>
<body>
Hello, World!
</body>
</html>
import eel
def main():
eel.init("web")
# Javascript 側の引数のない関数を呼び出す。
eel.echo("Hello")
eel.start("index.html", size=(1024, 768), port=8080)
if __name__ == "__main__":
main()
引数がある関数
Python 側では Javascript の関数は非同期で呼び出されるため、呼び出し完了後に実行する関数を引数で指定します。
<!DOCTYPE html>
<html>
<head>
<title>Hello, World!</title>
<!-- Include eel.js - note this file doesn't exist in the 'web' directory -->
<script type="text/javascript" src="/eel.js"></script>
<script>
eel.expose(add);
function add(a, b) {
return a + b;
}
</script>
</head>
<body>
Hello, World!
</body>
</html>
import eel
def print_ret(ret):
print("ret", ret)
def main():
eel.init("web")
eel.add(1, 2)(print_ret)
# Javascript 側の引数のある関数を呼び出す。
eel.start("index.html", size=(1024, 768), port=8080)
if __name__ == "__main__":
main()
Python の関数を Javascript から呼び出す
引数がない関数
Python の関数を Javascript から利用したい場合は、@eel.expose
デコレーターを呼び出したい関数につけます。Javascript 側からは eel.<関数名>(<引数一覧>)
で呼び出せます。関数は非同期で実行されます。
<!DOCTYPE html>
<html>
<head>
<title>Hello, World!</title>
<!-- Include eel.js - note this file doesn't exist in the 'web' directory -->
<script type="text/javascript" src="/eel.js"></script>
<script>
eel.echo("Hello");
</script>
</head>
<body>
Hello, World!
</body>
</html>
import eel
@eel.expose
def echo(msg):
print(msg)
def main():
eel.init("web")
eel.start("index.html", size=(1024, 768), port=8080)
if __name__ == "__main__":
main()
引数がある関数
Javascript 側では Python の関数は非同期で呼び出されるため、async 関数内で await を使用して結果を受け取る必要があります。
<!DOCTYPE html>
<html>
<head>
<title>Hello, World!</title>
<!-- Include eel.js - note this file doesn't exist in the 'web' directory -->
<script type="text/javascript" src="/eel.js"></script>
<script>
async function test() {
let result = await eel.add(1, 2)();
console.log(result);
}
test();
</script>
</head>
<body>
Hello, World!
</body>
</html>
import eel
@eel.expose
def add(a, b):
return a + b
def main():
eel.init("web")
eel.start("index.html", size=(1024, 768), port=8080)
if __name__ == "__main__":
main()
オブジェクトをやり取りする場合
オブジェクトをやり取りする場合、そのオブジェクトが JSON 化できるという要件 (json.dumps() で変換できる) を満たす必要があります。JSON 化ができないオブジェクトを引数や返り値に指定した場合、エラーになります。
Vue3 を Eel で使用する
1. インストールする
eel_templates/eel_vue に以下の手順で作成したテンプレートファイルがあります。
Node.js と Vue CLI がインストールされていない場合は、インストールします。
2. プロジェクトディレクトリを作成する
mkdir eel_example
cd eel_example
3. Vue をインストールする
Vue をインストールします。インストール時の設定は好みで選択してください。
vue create vue
? Please pick a preset: Manually select features
? Check the features needed for your project:
(*) Choose Vue version
(*) Babel
( ) TypeScript
( ) Progressive Web App (PWA) Support
(*) Router
( ) Vuex
>(*) CSS Pre-processors
(*) Linter / Formatter
( ) Unit Testing
( ) E2E Testing
? Choose a version of Vue.js that you want to start the project with
2.x
> 3.x
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): (Use arrow keys)
> Sass/SCSS (with dart-sass)
Sass/SCSS (with node-sass)
Less
Stylus
? Pick a linter / formatter config: (Use arrow keys)
> ESLint with error prevention only
ESLint + Airbnb config
ESLint + Standard config
ESLint + Prettier
? Pick additional lint features:
(*) Lint on save
>( ) Lint and fix on commit
? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
> In dedicated config files
In package.json
4. index.html を編集する
vue/public/index.html
を編集し、<script type="text/javascript" src="/eel.js"></script>
を挿入します。
<title>
<%= htmlWebpackPlugin.options.title %>
</title>
+ <script type=text/javascript src=/eel.js></script>
</head>
5. vue/vue.config.js を追加する
ビルドした際の出力ディレクトリが <project_dir>/web
になるように vue/vue.config.js
を作成し、設定を記載します。
module.exports = {
outputDir: "../web"
}
6. ビルドする
ビルドを行うと、<project_dir>/web
にコンパイルしたファイルが出力されます。
npm run build
7. .py ファイルを編集する
<project_dir>/app.py
を作成します。
import eel
# Set web files folder
eel.init("web")
eel.start("hello.html", size=(1024, 768))
8. 起動する
app.py
を実行すると、GUI 画面が表示されます。
python app.py
コメント