rawpython / remi

Python REMote Interface library. Platform independent. In about 100 Kbytes, perfect for your diet.
Apache License 2.0
3.48k stars 401 forks source link

How to shutdown the web server and GUI from user action #452

Closed m-kareem closed 2 years ago

m-kareem commented 3 years ago

Hello @dddomodossola ,

Thanks again for your kind and continues support. I need to add a shutdown button to my GUI to close the GUI and terminate the entire web service. I tried the self.close() and sys.exit(0) but neither worked as expected. I get the GUI down in the browser but the web service is still running and throwing error and stays at this stage for ever (please see the terminal output below).

Here is part of the code and the terminal output after user pressed shutdown button.

Please note that I am running the self.Shutdown_Lib() function in a separate thread as the shutting down process might take some time to talk to the actual hardwares and I don't want the GUI freezes during this time. (Currently this function only calls self.close() and sys.exit(0), but later I will add the actual hardwares shutdown functions here too.)

I would be very thankful if you can advice how to solve this issue.

All the best,


def on_btStopLib_pressed(self, widget):
        logger.debug("user pressed shutdown button")
        self.Lib_term_popup_confirm.show()
        self.Lib_term_popup_confirm.onconfirm.do(self.prep_Shutdown_Lib)

def prep_Shutdown_Lib(self, widget):
        self.btStopLib.attributes["disabled"] = ""
        self.btStartTC.attributes["disabled"] = ""
        currentDT = datetime.datetime.now()
        current_text= self.statusBox.get_text()
        self.statusBox.set_text(current_text+"["+currentDT.strftime("%H:%M:%S")+"] -- Shutting down all tasks and core_loop\n")

        self.thread_Shutdown_Lib = threading.Thread(target=self.Shutdown_Lib)
        self.thread_Shutdown_Lib.start()

def Shutdown_Lib(self):
        time.sleep(1)
        self.close()
        sys.exit(0)

------ terminal output ---- main DEBUG user pressed shutdown button remi.server.ws ERROR Error managing incoming websocket message Traceback (most recent call last): File "/Users/mkareem/.local/share/virtualenvs/coldbox_controller_webgui-QKVFYQ7h/lib/python3.8/site-packages/remi/server.py", line 164, in read_next_message length = self.bytetonum(length[1]) & 127 IndexError: index out of range

dddomodossola commented 3 years ago

Hello @m-kareem ,

You should not run self.close() in an external thread. Here is a working example:

import remi.gui as gui
from remi import start, App

class MyApp(App):
    def main(self, name='world'):
        # margin 0px auto allows to center the app to the screen
        wid = gui.VBox(width=300, height=200, margin='0px auto')

        bt = gui.Button('Close App', width=200, height=30)
        bt.style['margin'] = 'auto 50px'
        bt.style['background-color'] = 'red'

        bt.onclick.do(self.on_button_pressed)

        wid.append(bt)
        return wid

    # listener function
    def on_button_pressed(self, _):
        self.execute_javascript("window.close();")
        self.close()  # closes the application

    def on_close(self):
        """ Overloading App.on_close event allows to perform some 
             activities before app termination.
        """
        print("I'm going to be closed.")
        super(MyApp, self).on_close()

if __name__ == "__main__":
    start(MyApp)
m-kareem commented 2 years ago

Thanks @dddomodossola , this solved the issue. I am closing it now. All the best.