section_action_events.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. from nicegui import app, ui
  2. from . import (
  3. clipboard_documentation,
  4. doc,
  5. generic_events_documentation,
  6. keyboard_documentation,
  7. refreshable_documentation,
  8. run_javascript_documentation,
  9. storage_documentation,
  10. timer_documentation,
  11. )
  12. doc.title('Action & *Events*')
  13. doc.intro(timer_documentation)
  14. doc.intro(keyboard_documentation)
  15. @doc.demo('UI Updates', '''
  16. NiceGUI tries to automatically synchronize the state of UI elements with the client,
  17. e.g. when a label text, an input value or style/classes/props of an element have changed.
  18. In other cases, you can explicitly call `element.update()` or `ui.update(*elements)` to update.
  19. The demo code shows both methods for a `ui.echart`, where it is difficult to automatically detect changes in the `options` dictionary.
  20. ''')
  21. def ui_updates_demo():
  22. from random import random
  23. chart = ui.echart({
  24. 'xAxis': {'type': 'value'},
  25. 'yAxis': {'type': 'value'},
  26. 'series': [{'type': 'line', 'data': [[0, 0], [1, 1]]}],
  27. })
  28. def add():
  29. chart.options['series'][0]['data'].append([random(), random()])
  30. chart.update()
  31. def clear():
  32. chart.options['series'][0]['data'].clear()
  33. ui.update(chart)
  34. with ui.row():
  35. ui.button('Add', on_click=add)
  36. ui.button('Clear', on_click=clear)
  37. doc.intro(refreshable_documentation)
  38. @doc.demo('Async event handlers', '''
  39. Most elements also support asynchronous event handlers.
  40. Note: You can also pass a `functools.partial` into the `on_click` property to wrap async functions with parameters.
  41. ''')
  42. def async_handlers_demo():
  43. import asyncio
  44. async def async_task():
  45. ui.notify('Asynchronous task started')
  46. await asyncio.sleep(5)
  47. ui.notify('Asynchronous task finished')
  48. ui.button('start async task', on_click=async_task)
  49. doc.intro(generic_events_documentation)
  50. @doc.demo('Running CPU-bound tasks', '''
  51. NiceGUI provides a `cpu_bound` function for running CPU-bound tasks in a separate process.
  52. This is useful for long-running computations that would otherwise block the event loop and make the UI unresponsive.
  53. The function returns a future that can be awaited.
  54. ''')
  55. def cpu_bound_demo():
  56. import time
  57. from nicegui import run
  58. def compute_sum(a: float, b: float) -> float:
  59. time.sleep(1) # simulate a long-running computation
  60. return a + b
  61. async def handle_click():
  62. result = await run.cpu_bound(compute_sum, 1, 2)
  63. ui.notify(f'Sum is {result}')
  64. # ui.button('Compute', on_click=handle_click)
  65. # END OF DEMO
  66. async def mock_click():
  67. import asyncio
  68. await asyncio.sleep(1)
  69. ui.notify('Sum is 3')
  70. ui.button('Compute', on_click=mock_click)
  71. @doc.demo('Running I/O-bound tasks', '''
  72. NiceGUI provides an `io_bound` function for running I/O-bound tasks in a separate thread.
  73. This is useful for long-running I/O operations that would otherwise block the event loop and make the UI unresponsive.
  74. The function returns a future that can be awaited.
  75. ''')
  76. def io_bound_demo():
  77. import requests
  78. from nicegui import run
  79. async def handle_click():
  80. URL = 'https://httpbin.org/delay/1'
  81. response = await run.io_bound(requests.get, URL, timeout=3)
  82. ui.notify(f'Downloaded {len(response.content)} bytes')
  83. ui.button('Download', on_click=handle_click)
  84. doc.intro(run_javascript_documentation)
  85. doc.intro(clipboard_documentation)
  86. @doc.demo('Events', '''
  87. You can register coroutines or functions to be called for the following events:
  88. - `app.on_startup`: called when NiceGUI is started or restarted
  89. - `app.on_shutdown`: called when NiceGUI is shut down or restarted
  90. - `app.on_connect`: called for each client which connects (optional argument: nicegui.Client)
  91. - `app.on_disconnect`: called for each client which disconnects (optional argument: nicegui.Client)
  92. - `app.on_exception`: called when an exception occurs (optional argument: exception)
  93. When NiceGUI is shut down or restarted, all tasks still in execution will be automatically canceled.
  94. ''')
  95. def lifecycle_demo():
  96. from datetime import datetime
  97. from nicegui import app
  98. # dt = datetime.now()
  99. def handle_connection():
  100. global dt
  101. dt = datetime.now()
  102. app.on_connect(handle_connection)
  103. label = ui.label()
  104. ui.timer(1, lambda: label.set_text(f'Last new connection: {dt:%H:%M:%S}'))
  105. # END OF DEMO
  106. global dt
  107. dt = datetime.now()
  108. @doc.demo(app.shutdown)
  109. def shutdown_demo():
  110. from nicegui import app
  111. # ui.button('shutdown', on_click=app.shutdown)
  112. #
  113. # ui.run(reload=False)
  114. # END OF DEMO
  115. ui.button('shutdown', on_click=lambda: ui.notify(
  116. 'Nah. We do not actually shutdown the documentation server. Try it in your own app!'))
  117. doc.intro(storage_documentation)