python-eel / Eel

A little Python library for making simple Electron-like HTML/JS GUI apps
MIT License
6.29k stars 582 forks source link

Close windows when python exits #668

Open bryaan opened 1 year ago

bryaan commented 1 year ago

During dev it's a pain to close all the eel windows when you need to restart eel for python code changes.

For development purposes, and since we don't yet have live-reload for python using eel, it would be helpful to close all the windows when the python program is quit.

I have the limitation that I am unable to call js from python in case that is part of your solution.

I thought of using a ping to eel and closing each window using this little script, but eel doesn't seem to throw the error while the function is being called.

    setInterval(pingEel, 250);

    function pingEel(a, b) {
      try {
        eel.ping_eel();
      } catch (error) {
        console.log("Ping to eel failed, python must be closed.  Closing windows.")
        window.close()
      }
    }
gabrielerandazzo commented 1 year ago

I had the same problem, the program closed when my pc entered in sleep mode, but the browser's window didn't close. I solved it by starting eel from a thread and using a webview through QtPy instead of a browser so that i could have full control over the GUI.

Eg.

from qtpy.QtCore import QUrl
from qtpy.QtWidgets import QApplication, QMainWindow
from qtpy.QtWebEngineWidgets import QWebEngineView
from PyQt5 import QtGui
import threading
import time
import sys

class Browser(QMainWindow):
    def __init__(self):
        super().__init__()
        print("my browser")
        self.browser = QWebEngineView()
        self.browser.setUrl(QUrl("http://localhost:8000/index.html"))
        self.setCentralWidget(self.browser)

def gui():
    eel.init('web')
    #Your eel exposed function here...
    eel.start('index.html',mode=None ,close_callback=close)
gui_t = threading.Thread(target = gui)
gui_t.daemon=True
gui_t.start()
time.sleep(2) #wait for eel to start

app = QApplication([])
window = Browser()
window.showMaximized()
sys.exit(app.exec_())
thatfloflo commented 1 year ago

Especially for @gabrielerandazzo's scenario I think something that maybe ought to be looked at is whether signal handlers can be implemented to trigger a graceful shutdown of eel's gevent loop/hub. That could also pass the signal along the websockets to that browser windows can be closed if desirable. I'm not completely sure whether manually closing the terminal would reliably trigger the right signal handling avenue, but in principle it should go some way to address these issues...

I believe on sleep most POSIX systems will send signal.SIGALRM, but signalSIGABRT, signal.SIGBREAK, signal.SIGINT, signal.SIGKILL, signal.SIGTERM and signal.SIGQUIT should probably be handled in a similar way... shouldn't be too difficult to implement, I could potentially write a PR to do that...