main.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  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 re
  11. # add docutils css to webpage
  12. wp.head_html += docutils.core.publish_parts('', writer_name='html')['stylesheet']
  13. @contextmanager
  14. def example(content: Union[Element, str]):
  15. callFrame = inspect.currentframe().f_back.f_back
  16. begin = callFrame.f_lineno
  17. with ui.row(classes='flex w-full'):
  18. if isinstance(content, str):
  19. ui.markdown(content, classes='mr-8 w-4/12')
  20. else:
  21. doc = content.__init__.__doc__
  22. if doc:
  23. html = docutils.core.publish_parts(doc, writer_name='html')['html_body']
  24. html = html.replace('<p>', '<h3>', 1)
  25. html = html.replace('</p>', '</h3>', 1)
  26. html = Markdown.apply_tailwind(html)
  27. ui.html(html, classes='mr-8 w-4/12')
  28. else:
  29. ui.label(content.__name__, 'h5')
  30. with ui.card(classes='mt-12 w-2/12'):
  31. yield
  32. callFrame = inspect.currentframe().f_back.f_back
  33. end = callFrame.f_lineno
  34. code = inspect.getsource(sys.modules[__name__])
  35. code = code.splitlines()[begin:end]
  36. code = [l[4:] for l in code]
  37. code.insert(0, '```python')
  38. code.insert(1, 'from nicegui import ui')
  39. code.append('```')
  40. code = '\n'.join(code)
  41. ui.markdown(code, classes='mt-12 w-5/12 overflow-auto')
  42. with ui.row(classes='flex w-full'):
  43. with open('README.md', 'r') as file:
  44. content = file.read()
  45. content = re.sub(r'(?m)^\<img.*\n?', '', content)
  46. ui.markdown(content, classes='w-6/12')
  47. with ui.card(classes='w-4/12 mx-auto mt-24'):
  48. with ui.row(classes='s-x-16'):
  49. with ui.column():
  50. ui.button('Click me!', on_click=lambda: output.set_text('Click'))
  51. ui.checkbox('Check me!', on_change=lambda e: output.set_text('Checked' if e.value else 'Unchecked'))
  52. ui.switch('Switch me!', on_change=lambda e: output.set_text('Switched' if e.value else 'Unswitched'))
  53. ui.input(label='Text', value='abc', on_change=lambda e: output.set_text(e.value))
  54. ui.number(label='Number', value=3.1415927, format='%.2f', on_change=lambda e: output.set_text(e.value))
  55. with ui.column():
  56. ui.slider(min=0, max=100, value=50, step=0.1, on_change=lambda e: output.set_text(e.value))
  57. ui.radio(options=['A', 'B', 'C'], value='A', design='inline',
  58. on_change=lambda e: output.set_text(e.value))
  59. ui.toggle(['1', '2', '3'], value='1', classes='mx-auto', on_change=lambda e: output.set_text(e.value))
  60. ui.select(options={1: 'One', 2: 'Two', 3: 'Three'}, value=1, classes='mx-auto',
  61. on_change=lambda e: output.set_text(e.value))
  62. with ui.column():
  63. ui.label('Output:')
  64. output = ui.label(' ', 'bold')
  65. design = '''### Styling & Design
  66. 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):
  67. Have a look at [the Quasar documentation](https://quasar.dev/vue-components/button#design) for all styling "props".
  68. You can also apply [Tailwind](https://tailwindcss.com/) utility classes with the `classes` property.
  69. '''
  70. with (example(design)):
  71. ui.radio(['x', 'y', 'z'], design='inline color=green')
  72. ui.button(icon='touch_app', design='outline round', classes='shadow-lg ml-14')
  73. with example(ui.timer):
  74. from datetime import datetime
  75. clock = ui.label()
  76. t = ui.timer(interval=0.1, callback=lambda: clock.set_text(datetime.now().strftime("%X")))
  77. ui.checkbox('active').bind_value(t.active)
  78. with example(ui.label):
  79. ui.label('some label')
  80. with example(ui.markdown):
  81. ui.markdown('### Headline\nWith hyperlink to [GitHub](https://github.com/zauberzeug/nicegui).')
  82. with example(ui.html):
  83. ui.html('<p>demo paragraph in <strong>html</strong></p>')
  84. with example(ui.button):
  85. def button_increment():
  86. global button_count
  87. button_count += 1
  88. button_result.set_text(f'pressed: {button_count}')
  89. button_count = 0
  90. ui.button('Button', on_click=button_increment)
  91. button_result = ui.label('pressed: 0')
  92. with example(ui.checkbox):
  93. ui.checkbox('check me', on_change=lambda e: checkbox_state.set_text(e.value))
  94. with ui.row():
  95. ui.label('the checkbox is:')
  96. checkbox_state = ui.label('False')
  97. with example(ui.switch):
  98. ui.switch('switch me', on_change=lambda e: switch_state.set_text("ON" if e.value else'OFF'))
  99. with ui.row():
  100. ui.label('the switch is:')
  101. switch_state = ui.label('OFF')
  102. with example(ui.slider):
  103. slider = ui.slider(min=0, max=100, value=50, design='label')
  104. ui.label().bind_text_from(slider.value)
  105. with example(ui.input):
  106. ui.input(
  107. label='Text',
  108. placeholder='press ENTER to apply',
  109. on_change=lambda e: result.set_text('you typed: ' + e.value),
  110. classes='w-full',
  111. )
  112. result = ui.label('')
  113. with example(ui.number):
  114. number_input = ui.number(label='Number', value=3.1415927, format='%.2f')
  115. with ui.row():
  116. ui.label('underlying value: ')
  117. ui.label().bind_text_from(number_input.value)
  118. with example(ui.radio):
  119. radio = ui.radio(options=[1, 2, 3], value=1, design='inline')
  120. ui.radio(options={1: 'A', 2: 'B', 3: 'C'}, value=1, design='inline').bind_value(radio.value)
  121. with example(ui.toggle):
  122. toggle = ui.toggle(options=[1, 2, 3], value=1)
  123. ui.toggle(options={1: 'A', 2: 'B', 3: 'C'}, value=1).bind_value(toggle.value)
  124. with example(ui.select):
  125. with ui.row():
  126. select = ui.select(options=[1, 2, 3], value=1, design='inline')
  127. ui.select(options={1: 'One', 2: 'Two', 3: 'Three'}, value=1, design='inline').bind_value(select.value)
  128. with example(ui.plot):
  129. from matplotlib import pyplot as plt
  130. import numpy as np
  131. with ui.plot(figsize=(2.5, 1.8)):
  132. x = np.linspace(0.0, 5.0)
  133. y = np.cos(2 * np.pi * x) * np.exp(-x)
  134. plt.plot(x, y, '-')
  135. plt.xlabel('time (s)')
  136. plt.ylabel('Damped oscillation')
  137. with example(ui.line_plot):
  138. lines = ui.line_plot(n=2, limit=20, figsize=(2.5, 1.8)).with_legend(['sin', 'cos'], loc='upper center', ncol=2)
  139. line_updates = ui.timer(0.1, lambda: lines.push([datetime.now()], [
  140. [np.sin(datetime.now().timestamp()) + 0.02 * np.random.randn()],
  141. [np.cos(datetime.now().timestamp()) + 0.02 * np.random.randn()],
  142. ]), active=False)
  143. ui.checkbox('active').bind_value(line_updates.active)