0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Electron と Python の連携

Posted at

Electron と Python の連携

Electron(画面を作るのが得意)Python(計算やデータ処理が得意) を組み合わせて、最強のデスクトップアプリを作る方法について解説します。

「言語が違うのにどうやって会話するの?」と不思議に思うかもしれませんが、実は意外とシンプルな方法で連携できるんです。


連携の仕組み:主な2つの方法

Electron(Node.js)とPythonをつなぐ方法は、大きく分けて2つのアプローチがあります。

方法1:標準出力(Stdout)を使う方法

これは、ElectronがPythonファイルを「実行(Spawn)」し、Pythonがprint()した内容をElectronが「読み取る」方法です。

  • 流れ:
    1. Electron「ねえPython、このスクリプト動かして!」
    2. Python「処理終わったよ!結果をprintするね!」
    3. Electron「(コンソールに出てきた文字を読んで)なるほど、結果はこれか」

方法2:Web API(HTTP通信)を使う方法

こちらは、Pythonで小さな「Webサーバー(FastAPIなど)」を立ち上げ、ElectronからWebサイトを見るようにアクセスする方法です。

  • 流れ:
    1. Python「ローカルサーバー(localhost:8000)を立ち上げて待ってるよ」
    2. Electron「このURLにデータを送って、結果をちょうだい(HTTPリクエスト)」
    3. Python「OK!計算してJSONで返すね」

メリット・デメリット

本格的に開発するならどちらが良いか、表で比較してみましょう。

特徴 方法1:標準出力 (Print) 方法2:Web API (FastAPI)
手軽さ ◎ とても簡単。ファイル1つで済む △ Webサーバーの知識が少し必要
データのやり取り △ 文字列のみ。複雑なデータは苦手 ◎ JSON形式で複雑なデータも楽々
処理の並列性 △ Pythonが動いている間、止まりがち ◎ 非同期通信が得意。画面が固まらない
拡張性 △ 規模が大きくなると管理が大変 ◎ 機能追加しやすく、構造がきれい
既存資産の活用 △ スクリプト単位での再利用 ◎ Python側をそのままWebバックエンドに転用可

結論:本格開発なら「方法2(Web API)」がおすすめ

ちょっとしたスクリプトを動かすだけなら「方法1」でも十分ですが、将来的に機能を増やしたり、エラー処理をしっかりやりたい場合は「方法2」が圧倒的に有利

Web開発の標準的な技術(HTTP通信)を使うため、困ったときに情報が見つかりやすいのも大きなメリットであり、生成AIの恩恵も受けられやすい


ハンズオン

それでは、「方法2(FastAPI連携)」 で、最小構成のアプリを作ってみましょう。
ボタンを押すと、Pythonが挨拶を返してくれるシンプルなアプリです。

事前準備

  • Node.js がインストールされていること
  • Python がインストールされていること

Step 1: プロジェクトのセットアップ

適当なフォルダ(例: electron-python-app)を作り、ターミナルで以下を実行してライブラリを入れましょう。

# フォルダ作成と移動
mkdir electron-python-app
cd electron-python-app

# Pythonのライブラリ(FastAPIとサーバー)をインストール
pip install fastapi uvicorn

# Electronの初期化とインストール
npm init -y
npm install electron --save-dev

Step2: Pythonサーバー作成(api.py)

まずは「裏方」となるPythonファイルを作成します。

api.py
# api.py
from fastapi import FastAPI
import uvicorn

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "Hello from Python!"}

@app.get("/greet/{name}")
def read_item(name: str):
    return {"message": f"こんにちは、{name}さん!Pythonより愛を込めて。"}

if __name__ == "__main__":
    # ポート8000でサーバーを起動
    uvicorn.run(app, host="127.0.0.1", port=8000)
  • 解説: これだけで立派なWebサーバーです。localhost:8000/greet/あなたの名前 にアクセスすると、JSONデータが返ってきます

Step3: Electronの画面を作る (index.html)

次に「見た目」を作ります。

index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Electron + Python</title>
</head>
<body style="font-family: sans-serif; text-align: center; padding: 50px;">
    <h1>Electron 🤝 Python</h1>
    <input type="text" id="nameInput" placeholder="名前を入れてね" />
    <button id="sendBtn">送信</button>
    
    <h2 id="result" style="color: blue; margin-top: 20px;"></h2>

    <script>
        const btn = document.getElementById('sendBtn');
        const resultArea = document.getElementById('result');
        const input = document.getElementById('nameInput');

        btn.addEventListener('click', async () => {
            const name = input.value;
            // Pythonサーバー(FastAPI)にアクセス!
            try {
                const response = await fetch(`http://127.0.0.1:8000/greet/${name}`);
                const data = await response.json();
                resultArea.innerText = data.message;
            } catch (error) {
                resultArea.innerText = "エラー: API取得失敗";
            }
        });
    </script>
</body>
</html>

Step4: Electronのメインプロセス作成(main.js)

最後に、アプリの起動とPythonサーバーの管理をするファイルです。 「アプリ起動時にPythonも一緒に起動し、アプリ終了時にPythonも止める」 という処理を書きます。

main.js
const { app, BrowserWindow } = require('electron');
const path = require('path');
const { spawn } = require('child_process');

let mainWindow;
let pythonProcess;

function createWindow() {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true, // 簡易化のため有効化
    },
  });

  mainWindow.loadFile('index.html');
}

// アプリ起動時の処理
app.whenReady().then(() => {
  // 1. Pythonサーバーを裏でこっそり起動
  console.log('Start Python server...');
  pythonProcess = spawn('python', ['api.py']);
  // ※ Mac/Linuxの場合は 'python3' かもしれません

  // PythonのログをElectronのコンソールに出す(デバッグ用)
  pythonProcess.stdout.on('data', (data) => {
    console.log(`Python: ${data}`);
  });

  // 2. ウィンドウを作る
  createWindow();
});

// アプリ終了時の処理
app.on('will-quit', () => {
  // Pythonプロセスを確実に殺す
  if (pythonProcess) {
    pythonProcess.kill();
  }
});

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

Step 5: 動作確認

package.json の scripts 部分を少し書き換えて、実行しやすくします。

package.json
{
  "name": "electron-python-app",
  "version": "1.0.0",
  "main": "main.js",
  "scripts": {
    "start": "electron main.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "devDependencies": {
    "electron": "^39.2.6"
  }
}

コマンドプロンプトで下記を実行
npm start

アプリが正常に動く‥はず
image.png

補足資料: 配布方法

開発環境では動いても、他の人のPCにはPythonが入っていないかもしれません。 そこで、「Pythonごとアプリに埋め込んで配布する(Embed)」 という方法を使います。

Python Embeddable Package とは?
Python公式が提供している「インストール不要の最小構成zip版Python」です。これをElectronアプリのフォルダの中にコピペして一緒に配ります。

手順の概要

  1. ダウンロード: Python公式サイトから Windows embeddable package (64-bit) というzipをダウンロードします。

  2. 配置: Electronプロジェクトの中に python_env などのフォルダを作り、zipの中身を全て展開します。

  3. 設定ファイルの変更: 展開した中にある python3xx._pth ファイルをメモ帳で開き、#import site の行の # を消して有効化します(これをしないとpipで入れたライブラリが読み込めません)。

  4. ライブラリのインストール: この埋め込みPythonに対して、FastAPIなどをインストールします。 (ターミナルで python_env/python.exe -m pip install fastapi uvicorn のように指定して実行)

  5. Electron側の修正: main.js で spawn('python', ...) としていた部分を、埋め込んだPythonのパス spawn('./python_env/python.exe', ...) に変更します。

少し難しく、手順も複雑ですが、これでpython環境ごとアプリを配布できます。

応用

現在、pythonのサーバーは8000番を使用していますが、このポートは使用されている可能性があります。動的に秋ポートを探すという処理を入れておくのが良いでしょう。また、ローカル環境とは言え、トークンによる認証設定も推奨します。少し難しい話になりましたね。

最後に

今回はElectron + Pythonという現代デスクトップアプリの王道について解説しました。
いいね、コメントどんどんよろしくお願いします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?