I am using electron and python together. I've gone through all the youtube videos and forums I can find on the subject of packaging an app with a python backend. Many of these tutorials are out of date and no longer work.
This is my process so far. ANY help would be incredibly appreciated!
SOFTWARE USED Editor: VSCode (Main code running)
•Set the python virtual environment in the electron app.
$ python3 -m venv env
$ source env/bin/activate
•Installing ELECTRON
cd ProjectFolder
$ npm init -y
$ npm install electron --save-dev --save-exact
•Change package.json to reflect these lines
{
"main": "main.js", // Make sure that is main.js
"scripts": {
"start": "electron ." // Update this
},
}
•Install pyinstaller to make executable version of python scripts
$ pip install pyinstaller
…then navigate to the env/include folder
$ pyinstaller -F MainPythonFile.py
•Compile the app for Mac OS
$ npm install electron-forge --save-dev
$ npx @electron-forge/cli import
$ npm start (to make sure it works)
$ npm run make (compiles the app)
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>APP WINDOW</title>
<link rel="stylesheet" href="../assets/css/main.css">
</head>
<body>
<div id="main">
<div id="TopRow">
<div>
<div id="window-title-container" >
<h2>Interface Test</h2>
</div>
</div>
</div>
<div id="row1">
<div id="left-container">
</div>
<div id="right-container">
<button id="DlgBtn">Browse</button>
<button id="CloseBtn">Close</button>
</div>
</div>
</div>
<script src="index.js"></script>
</body>
</html>
main.css
@import url('https://fonts.googleapis.com/css?family=Montserrat:300,600');
body {
background: #262626;
color:#111;
font-family: 'Montserrat';
margin:0;
}
#TopRow {
width: 450px;
margin-top:0px;
background:#272727;
align-items: center;
}
#window-title-container {
margin-left: 10px;
max-height: 35px;
background: #272727;
color: #fff;
}
#row1 {
width: 450px;
margin-top:5px;
background:#1A1A1A;
border-bottom: 2px solid #ffffff;
border-top: 2px solid #ffffff;
display: grid;
grid-template-columns: 50% auto;
}
#left-container {
padding: 20px;
background:#272727;
border-right: 1px solid #fff;
}
#left-container img {
align-content: center;
width: 100%;
height: 100%;
}
#right-container {
background:#272727;
display: grid;
grid-template-columns: 50% 50%;
grid-template-rows: 20%;
}
#DlgBtn {
border: 2px solid white;
border-radius: 20px;
background:#2f3446;
color:#ffffff;
padding-top: 12px;
padding-bottom: 25px;
padding-left: 20px;
padding-right: 20px;
margin-top: 160%;
margin-left: 10px;
margin-right: 10px;
cursor:pointer;
}
#CloseBtn {
border: 2px solid white;
border-radius: 20px;
background: #2f3446;
color: #ffffff;
padding-top: 12px;
padding-bottom: 25px;
padding-left: 20px;
padding-right: 20px;
margin-top: 160%;
margin-left: 10px;
margin-right: 10px;
cursor: pointer;
}
main.js
function createWindow () {
// Create the browser window.
const win = new BrowserWindow({
height: 375,
width: 500,
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true
}
})
win.loadFile('src/index.html')
// Open the DevTools.
win.webContents.openDevTools()
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow)
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {if (process.platform !== 'darwin') {app.quit()}})
app.on('activate', () => {
// On macOS 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()
}
})
index.js
const DlgBtn = document.getElementById('DlgBtn')
const CloseBtn = document.getElementById('CloseBtn')
// Dialog Button opens a file dialog and then proceeds to process the python scripts
DlgBtn.addEventListener(type ='click', function() {
const { dialog } = require('electron').remote;
const path = require('path');
var fs = require('fs');
// Synchronous method. This way the dialog can complete before the code moves on.
let dirs = dialog.showOpenDialogSync({properties:["openDirectory"]});
// In the actual functionality I pass a folder path to the pyhton script through JSON
fs.writeFileSync(path.resolve(__dirname, 'PythonParams.json'), JSON.stringify({"selected_dir":dirs}));
var python = require('child_process').spawn('python', ['./src/hello.py']);
python.stdout.on('data',function(data){console.log("data: ",data.toString('utf8'))})
})
// Close Button to close interface
CloseBtn.addEventListener(type ='click', function() {
window.close()
})
hello.py
print('Hello StackOverflow')
package.json
{
"name": "DEMO5",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"start": "electron ."
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"electron": "10.1.5"
}
}
It works fine until I compile with, well, any packager (electron-packager, electron-forge, etc...) It just does nothing as far as python goes. I'm new to frontend development and appreciate guidance/help in this area