nicegui.py 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. #!/usr/bin/env python3
  2. from typing import Awaitable, Callable
  3. import asyncio
  4. import binding
  5. from pygments.formatters import HtmlFormatter
  6. from starlette.routing import Route
  7. from starlette.responses import FileResponse
  8. from .ui import Ui # NOTE: before justpy
  9. import justpy as jp
  10. from .elements.element import Element
  11. from .timer import Timer
  12. wp = jp.QuasarPage(delete_flag=False, title=Ui.config.title, favicon=Ui.config.favicon)
  13. wp.tailwind = True # use Tailwind classes instead of Quasars
  14. wp.css = HtmlFormatter().get_style_defs('.codehilite')
  15. wp.head_html += '<script>confirm = () => true;</script>\n' # avoid confirmation dialog for reload
  16. main = jp.Div(a=wp, classes='q-ma-md column items-start', style='row-gap: 1em')
  17. main.add_page(wp)
  18. jp.justpy(lambda: wp, start_server=False)
  19. async def binding_loop():
  20. while True:
  21. binding.update()
  22. await asyncio.sleep(0.1)
  23. def create_task(coro):
  24. loop = asyncio.get_event_loop()
  25. return loop.create_task(coro)
  26. tasks = []
  27. @jp.app.on_event('startup')
  28. def startup():
  29. tasks.extend(create_task(t) for t in Timer.tasks)
  30. tasks.extend(create_task(t) for t in Ui.startup_tasks if isinstance(t, Awaitable))
  31. [t() for t in Ui.startup_tasks if isinstance(t, Callable)]
  32. jp.run_task(binding_loop())
  33. @jp.app.on_event('shutdown')
  34. def shutdown():
  35. [create_task(t) for t in Ui.shutdown_tasks if isinstance(t, Awaitable)]
  36. [t() for t in Ui.shutdown_tasks if isinstance(t, Callable)]
  37. [t.cancel() for t in tasks]
  38. Element.wp = wp
  39. Element.view_stack = [main]
  40. app = jp.app
  41. app.routes.insert(0, Route('/file', lambda r: FileResponse(r.query_params['path'])))
  42. ui = Ui()