main.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #!/usr/bin/env python3
  2. from nicegui import ui, wp
  3. from contextlib import contextmanager
  4. import inspect
  5. from nicegui.elements.markdown import Markdown
  6. from nicegui.elements.element import Element
  7. import sys
  8. from typing import Union
  9. import docutils.core
  10. import icecream
  11. icecream.install()
  12. # add docutils css to webpage
  13. wp.head_html += docutils.core.publish_parts('', writer_name='html')['stylesheet']
  14. @contextmanager
  15. def example(content: Union[Element, str]):
  16. callFrame = inspect.currentframe().f_back.f_back
  17. begin = callFrame.f_lineno
  18. with ui.row(classes='flex w-full'):
  19. if isinstance(content, str):
  20. ui.markdown(content, classes='mr-8 w-4/12')
  21. else:
  22. doc = content.__init__.__doc__
  23. if doc:
  24. html = docutils.core.publish_parts(doc, writer_name='html')['html_body']
  25. html = html.replace('<p>', '<h3>', 1)
  26. html = html.replace('</p>', '</h3>', 1)
  27. html = Markdown.apply_tailwind(html)
  28. ui.html(html, classes='mr-8 w-4/12')
  29. else:
  30. ui.label(content.__name__, 'h5')
  31. with ui.card(classes='mt-12 w-2/12'):
  32. yield
  33. callFrame = inspect.currentframe().f_back.f_back
  34. end = callFrame.f_lineno
  35. code = inspect.getsource(sys.modules[__name__])
  36. code = code.splitlines()[begin:end]
  37. code = [l[4:] for l in code]
  38. code.insert(0, '```python')
  39. code.insert(1, 'from nicegui import ui')
  40. code.append('```')
  41. code = '\n'.join(code)
  42. ui.markdown(code, classes='mt-12 w-5/12 overflow-auto')
  43. with open('README.md', 'r') as file:
  44. ui.markdown(file.read())
  45. design = '''### Styling & Design
  46. NiceGUI use the [Quasar Framework](https://quasar.dev/) and hence has their full design power. Each NiceGUI element provides a `design` property which content is passed [as props the Quasar component](https://justpy.io/quasar_tutorial/introduction/#props-of-quasar-components):
  47. Have a look at [the Quasar documentation](https://quasar.dev/vue-components/button#design) for all styling "props".
  48. You can also apply [Tailwind](https://tailwindcss.com/) utility classes with the `classes` property.
  49. '''
  50. with (example(design)):
  51. ui.radio(['x', 'y', 'z'], design='inline color=green')
  52. ui.button(icon='touch_app', design='outline round', classes='shadow-lg ml-14')
  53. with example(ui.timer):
  54. from datetime import datetime
  55. clock = ui.label()
  56. t = ui.timer(interval=0.1, callback=lambda: clock.set_text(datetime.now().strftime("%X")))
  57. ui.checkbox('active').bind_value(t.active)
  58. with example(ui.button):
  59. def button_increment():
  60. global button_count
  61. button_count += 1
  62. button_result.set_text(f'pressed: {button_count}')
  63. button_count = 0
  64. ui.button('Button', on_click=button_increment)
  65. button_result = ui.label('pressed: 0')
  66. with example(ui.input):
  67. ui.input(
  68. label='Text',
  69. placeholder='press ENTER to apply',
  70. on_change=lambda e: result.set_text('you typed: ' + e.value)
  71. )
  72. result = ui.label('')
  73. with example(ui.plot):
  74. from matplotlib import pyplot as plt
  75. import numpy as np
  76. with ui.plot(figsize=(2.5, 1.8)):
  77. x = np.linspace(0.0, 5.0)
  78. y = np.cos(2 * np.pi * x) * np.exp(-x)
  79. plt.plot(x, y, '-')
  80. plt.xlabel('time (s)')
  81. plt.ylabel('Damped oscillation')
  82. with example(ui.line_plot):
  83. lines = ui.line_plot(n=2, limit=20, figsize=(2.5, 1.8)).with_legend(['sin', 'cos'], loc='upper center', ncol=2)
  84. line_updates = ui.timer(0.1, lambda: lines.push([datetime.now()], [
  85. [np.sin(datetime.now().timestamp()) + 0.02 * np.random.randn()],
  86. [np.cos(datetime.now().timestamp()) + 0.02 * np.random.randn()],
  87. ]), active=False)
  88. ui.checkbox('active').bind_value(line_updates.active)