Compile Python runtime inside of electron app

Viewed 730

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"
  }
}

enter image description here 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

0 Answers
Related