I am trying to experiment with GUIs in Python, and since I like web development I found eel which allows the use of HTML, CSS and JS in Python GUIs. However, I noticed that it relies on certain browsers being installed, but had an option for electron. I installed electron with npm install electron and used the example electron template provided at the official Github repo modified it a bit to support my need.
Project Structure:
chatApp/
|--node_modules/
|--web/
| |--home/
| | |--index.html
| |--include/
| | |--css/
| | | |--style.css
| | |--js/
| | | |--main.js
| |--index.html
|--app.py
|--index.js
The PyInstaller command:
pyinstaller app.py --hidden-import bottle_websocket --add-data "C:\Users\coder\AppData\Local\Programs\Python\Python310\lib\site-packages\eel\eel.js;eel" --add-data "web;web" --add-data "node_modules;node_modules" --add-data "index.js;index" --onefile --noconsole
app.py:
# Allow for --noconsole
import sys, io
buffer = io.StringIO()
sys.stdout = sys.stderr = buffer
# Main Code
import eel
SERVERS = {
"general": {"users": [], "messages": {}},
}
eel.init("web")
@eel.expose
def join_server(server_name):
if server_name not in SERVERS:
SERVERS[server_name] = {"users": [], "messages": {}}
SERVERS[server_name]["users"].append(eel.get_user()())
# eel.start('/home/index.html', mode='custom', cmdline_args=["./node_modules/electron/dist/electron.exe", "./index.js"]) # For Testing
eel.start("/home/index.html", mode="custom", cmdline_args=["./node_modules/electron/dist/electron.exe", "./index/index.js"]) # For build
index.js
// Modules to control application life and create native browser window
const {app, BrowserWindow} = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// Remove the menu bar
mainWindow.removeMenu();
// and load the index.html of the app.
mainWindow.loadURL('http://localhost:8000/index.html');
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
app.quit();
})
}
// 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.on('ready', createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') app.quit()
})
app.on('activate', function () {
// 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 (mainWindow === null) 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 require them here.
Here is the error it gives: File Not Found Error
Yet it works just fine with the PyInstaller command without the --onefile:
pyinstaller app.py --hidden-import bottle_websocket --add-data "C:\Users\coder\AppData\Local\Programs\Python\Python310\lib\site-packages\eel\eel.js;eel" --add-data "web;web" --add-data "node_modules;node_modules" --add-data "index.js;index" --noconsole
It results in this: Working Electron App
I have tried replacing the ./ with / and nothing as well as changed all the / with \\ in cmdline_args=["./node_modules/electron/dist/electron.exe", "./index/index.js"]. I can't think of anything else to try and fix the error as it says that the file cannot be found which I would assume means that the path is incorrect.