※正しい方法かはわからないので、使用する際は自身で検証してください。
Electronとpython-shellを使ったアプリを作ろうと思い、調べた結果をまとめる。
(実際には作ってない。)
1.Electronアプリ作成
npx create-electron-app myapp
cd myapp
npm start
2.pythonの環境作成とactivate
cd src
python -m venv --copies py38
source py38/bin/activate
3.ElectronでPythonを使用するためにpython-shellをインストール。
npm install python-shell
python -m pip install python-shell
4.preload.jsを作成する。
preload.js
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('myapi',{
send: async (data) => await ipcRenderer.invoke('showdir',data),
on : (channel,func) =>{
ipcRenderer.once(channel,(event,data)=>func(data))
}
})
contextBridge.exposeInMainWorld('myapi1',{
send: async (data) => await ipcRenderer.invoke('showexecute',data),
on : (channel,func) =>{
ipcRenderer.once(channel,(event,data)=>func(data))
}
})
5.index.jsとindex.htmlは下記のように変更
index.jsの下記を追加して、 PythonShell.runString に渡してあげると作成したpythonの環境を使用してくれている(はず)
const options = {
mode :'text',
pythonPath : __dirname + '/py38/bin/python'
}
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World!</title>
<link rel="stylesheet" href="index.css" />
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<p>wellcome!</p>
<div>
<button type="button" v-on:click="showdir">Button</button>
<button type="button" v-on:click="showexec">Button1</button>
</div>
</div>
</body>
<script>
const app = {
setup(){
},
data(){
return {
title : "TitleA"
}
},
methods:{
async showdir(){
const message = window.myapi.send({"send_data":"send"})
const message2 = window.myapi.on("return_data",async(data)=>{
alert(data)
})
},
async showexec(){
const message = window.myapi1.send({"send_data":"send"})
const message2 = window.myapi1.on("return_data1",async(data)=>{
alert(data)
})
}
}
}
Vue.createApp(app).mount('#app')
</script>
</html>
index.js
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');
const { PythonShell } = require('python-shell')
if (require('electron-squirrel-startup')) {
app.quit();
}
const createWindow = () => {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
},
});
// and load the index.html of the app.
mainWindow.loadFile(path.join(__dirname, 'index.html'));
// Open the DevTools.
mainWindow.webContents.openDevTools();
};
app.on('ready', createWindow);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and import them here.
const options = {
mode :'text',
pythonPath : __dirname + '/py38/bin/python'
}
ipcMain.handle('showdir', async (event,data)=>{
PythonShell.runString('import os; print(os.getcwd());',options,function(err,result){
if (err) throw err;
event.sender.send("return_data",result)
})
})
ipcMain.handle('showexecute', async (event,data)=>{
PythonShell.runString('import sys; print(sys.executable);',options,function(err,result){
if (err) throw err;
event.sender.send("return_data1",result)
})
})
6.アプリをビルドする。
npm run make
7.参考
こちらの記事を参考にしました。