#概要
electronはHTML, CSS, Javascriptを使って簡単にWindows, mac, linux のマルチプラットフォームにアプリを作成できるフレームワークです。
今回electronとpythonコードを連携させる際のファイル構造に関しての覚書です。
##electronにおけるFrontend,Backend間の情報のやり取りの変遷
https://qiita.com/pochman/items/64b34e9827866664d436
こちらの記事に詳しく書かれていますが、electronはこれまでversionが上がるたびにSecurityの観点からipc通信の仕様を変更しています。これから先も変更になる可能性はありますが、2021年4月の時点の情報です。
##main.js設定
const electron = require('electron');
const app = electron.app;
const path = require("path");
const BrowserWindow = electron.BrowserWindow;
const ipcMain = electron.ipcMain;
const ipcRenderer = electron.ipcRenderer;
//ここでpyhonshell library を呼び出す
const {PythonShell} = require("python-shell");
let mainWindow;
function createWindow() {
// メインウィンドウを作成します
mainWindow = new BrowserWindow({
width:1100,
height: 1000,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: path.join(__dirname, 'preload.js')
},
});
// メインウィンドウに表示するURLを指定します
// (今回はmain.jsと同じディレクトリのindex.html)
mainWindow.loadFile('index.html');
// デベロッパーツールの起動
mainWindow.webContents.openDevTools();
// メインウィンドウが閉じられたときの処理
mainWindow.on('closed', () => {
mainWindow = null;
});
}
// 初期化が完了した時の処理
app.on('ready', createWindow);
// 全てのウィンドウが閉じたときの処理
app.on('window-all-closed', () => {
// macOSのとき以外はアプリケーションを終了させます
if (process.platform !== 'darwin') {
app.quit();
}
});
// アプリケーションがアクティブになった時の処理(Macだと、Dockがクリックされた時)
app.on('activate', () => {
// メインウィンドウが消えている場合は再度メインウィンドウを作成する
if (mainWindow === null) {
createWindow();
}
});
//ここでpreload.jsからのipc通信を受け取り、python-shellを起動
//pythonで書かれたコードを呼び出す
ipcMain.handle('hoge',async (event, data) => {
//pythonに渡す何らかのパラメーター
var options = {
data:data
}
//ここでパラメーターと共に渡す
let pyshell =await new PythonShell('hogehoge.py', options);
//pythonでのコード処理が終わったらpythonからexportされたメッセージを受け取る
//preload.jsにpythonから吐き出されたデータを送る
pyshell.on('message', async function(message) {
event.sender.send("return_data", message)
})
})
preload.js
const { contextBridge, ipcRenderer} = require("electron")
//main.jsに書かれた"hoge" handlerを起動している
contextBridge.exposeInMainWorld('api', {
send: async (data) => await ipcRenderer.invoke('hoge', data),
on: (channel, func) => {
ipcRenderer.on(channel, (event, data) => func(data));
}
}
);
##index.html
<script>
//ここでpreload.jsで作成されたapiを呼び出して何らかのデータを渡す
const message= window.api.send({"send_data":send_data})
const message2=window.api.on("return_data", async (data)=>{
//returnされたデータを使った処理をこちらに書く
})
</script>
##最後に
electronを使用してpythonコードをつかったアプリを作る必要があったため、自分用としてまとめておきました。非常にざっくりとした記事ですが、どなたかのお役に立てれば幸いです。
もし不備などありましたらお知らせいただけると幸いです。