manatlan / guy

Graphics User Ynterface : a simple module for making GUI applications (with html/js) for py3 ... to target windows, linux, mac & android
Apache License 2.0
203 stars 23 forks source link

some improvements #27

Closed robert-boulanger closed 4 years ago

robert-boulanger commented 4 years ago

Currently im porting an existing QT App to guy. First, it's a great concept, neverthe less I want to suggest some improvements I've built in now into guy.py, but I want to explain and discuss why I did so, before making a change request.

As far as I understand the code, (async) def init is executed for every connecting client (means one time if running in CEF or App mode, once for every browser tab in SERVE mode.

What I'm missing is a kindof "cleanup" equivalent to init.

so I changed on_ close in WebSocketHandler the following way:

    def on_close(self):
        try:
            current=WebSocketHandler.clients[self]
            logger.debug("Disconnect %s",current._id)
            async def doCleanUp( instance ):
                cleanup=instance._getRoutage("cleanup")
                if cleanup:
                    if asyncio.iscoroutinefunction( cleanup ):
                        await instance(self,"cleanup")
                    else:
                        instance(self,"cleanup")

            asyncio.ensure_future(doCleanUp(current))
            del WebSocketHandler.clients[self]
        except KeyError:
            pass

The check for the KeyError is cleaner in my eyes, to avoid ugly logger entries when closing an "old" browser tab in SERVE MODE.

The next thing I changed is:

class WebServer(Thread): # the webserver is ran on a separated thread
    port = 39000
    def __init__(self,instance,host="localhost",port=None,autoreload=False):

            ......
            ......
           self.instance._webserver=(self.host,self.port)
           self.instance._tornado = self
           .......
           .......

I need the tornado instance, or better said it's event loop, to pass it over to a AsyncIOMotorClient instance for being able to use the async emit or emitMe methods when something happens inside a db changestream. But I can imagine, it is useful generally if something from "outside" happens which has to be emitted to the client.

So it is for example possible to initiate the AsyncDB Connection like this in the GUY App:

 async def init(self):
        if Classname.DBAsync is None:  # that's a static thing
            Classname.DBAsync = AsyncConnection(f"mongodb://{self.host}:{self.port}",io_loop = self._tornado.loop)
        await self.js.start()

Please let me know what you think,

best Robert

manatlan commented 4 years ago

hi

Currently im porting an existing QT App to guy.

Perhaps .. You should have a look to gtag (currently, it's a separated lib, but in a near future, gtag will be included in guy) : its a layer, on top of guy, to (really) easily make a GUI (in a more classical way). It should be a lot easier to migrate a qt app in a guy way.

What I'm missing is a kindof "cleanup" equivalent to init.

yes, you've right ... it can be very useful to close up some things !!! (the way you implemented fit well with the logic)

I need the tornado instance, or better said it's event loop I can understand the need ! no trouble!

Please let me know what you think, it's good for me

robert-boulanger commented 4 years ago

Ok, the pull request is done. I also added a afterServerStarted event which passes the webserver instance as well as the app instance back. Nevertheless i kept the _tornado attribute, since I found out, that in app and cef mode, init happens before. Whenever you need the eventloop, you need to have access to it at this moment.

One big please: Could you disable (or make it interuptable by a flag or somewhat else ) guy.exit() when sunning in server mode? This is a huge issue in my eyes.

BTW.

I had a look ad gtag already before i began. Although it's nice, but it is not an option for me. My GUI is rather complex, so I do this with the great webix library.

manatlan commented 4 years ago

sorry for the long delay PR is merged !