#!/usr/bin/env python3 from nicegui import ui, wp from contextlib import contextmanager import inspect from nicegui.elements.markdown import Markdown from nicegui.elements.element import Element import sys from typing import Union import docutils.core import re import asyncio # add docutils css to webpage wp.head_html += docutils.core.publish_parts('', writer_name='html')['stylesheet'] @contextmanager def example(content: Union[Element, str]): callFrame = inspect.currentframe().f_back.f_back begin = callFrame.f_lineno with ui.row().classes('flex w-full'): if isinstance(content, str): ui.markdown(content).classes('mr-8 w-4/12') else: doc = content.__init__.__doc__ if doc: html = docutils.core.publish_parts(doc, writer_name='html')['html_body'] html = html.replace('

', '

', 1) html = html.replace('

', '

', 1) html = Markdown.apply_tailwind(html) ui.html(html).classes('mr-8 w-4/12') else: ui.label(content.__name__).classes('text-h5') with ui.card().classes('mt-12 w-2/12'): yield callFrame = inspect.currentframe().f_back.f_back end = callFrame.f_lineno code = inspect.getsource(sys.modules[__name__]) code = code.splitlines()[begin:end] code = [l[4:] for l in code] code.insert(0, '```python') code.insert(1, 'from nicegui import ui') code.append('') code.append('ui.run()') code.append('```') code = '\n'.join(code) ui.markdown(code).classes('mt-12 w-5/12 overflow-auto') with ui.row().classes('flex w-full'): with open('README.md', 'r') as file: content = file.read() content = re.sub(r'(?m)^\ ''' ui.svg(svg_content) overlay = '''### Captions and Overlays By nesting elements inside a `ui.image` you can create augmentations. Use [Quasar classes](https://quasar.dev/vue-components/img) for positioning and styling captions. To overlay an svg, make the `viewBox` exactly the size of the image and provide `100%` width/height to match the actual rendered size. ''' with example(overlay): with ui.image('http://placeimg.com/640/360/nature'): ui.label('nice').classes('absolute-bottom text-subtitle2 text-center') with ui.image('https://cdn.pixabay.com/photo/2020/07/13/12/56/mute-swan-5400675__340.jpg'): svg_content = ''' ''' ui.svg(svg_content).style('background:transparent') with example(ui.markdown): ui.markdown('### Headline\nWith hyperlink to [GitHub](https://github.com/zauberzeug/nicegui).') with example(ui.html): ui.html('

demo paragraph in html

') with example(ui.button): def button_increment(): global button_count button_count += 1 button_result.set_text(f'pressed: {button_count}') button_count = 0 ui.button('Button', on_click=button_increment) button_result = ui.label('pressed: 0') with example(ui.checkbox): ui.checkbox('check me', on_change=lambda e: checkbox_state.set_text(e.value)) with ui.row(): ui.label('the checkbox is:') checkbox_state = ui.label('False') with example(ui.switch): ui.switch('switch me', on_change=lambda e: switch_state.set_text("ON" if e.value else'OFF')) with ui.row(): ui.label('the switch is:') switch_state = ui.label('OFF') with example(ui.slider): slider = ui.slider(min=0, max=100, value=50).props('label') ui.label().bind_text_from(slider.value) with example(ui.input): ui.input( label='Text', placeholder='press ENTER to apply', on_change=lambda e: result.set_text('you typed: ' + e.value), ).classes('w-full') result = ui.label('') with example(ui.number): number_input = ui.number(label='Number', value=3.1415927, format='%.2f') with ui.row(): ui.label('underlying value: ') ui.label().bind_text_from(number_input.value) with example(ui.radio): radio = ui.radio([1, 2, 3], value=1).props('inline') ui.radio({1: 'A', 2: 'B', 3: 'C'}, value=1).props('inline').bind_value(radio.value) with example(ui.toggle): toggle = ui.toggle([1, 2, 3], value=1) ui.toggle({1: 'A', 2: 'B', 3: 'C'}, value=1).bind_value(toggle.value) with example(ui.select): with ui.row(): select = ui.select([1, 2, 3], value=1).props('inline') ui.select({1: 'One', 2: 'Two', 3: 'Three'}, value=1).props('inline').bind_value(select.value) with example(ui.upload): ui.upload(on_upload=lambda files: content.set_text(files)) content = ui.label() with example(ui.plot): from matplotlib import pyplot as plt import numpy as np with ui.plot(figsize=(2.5, 1.8)): x = np.linspace(0.0, 5.0) y = np.cos(2 * np.pi * x) * np.exp(-x) plt.plot(x, y, '-') plt.xlabel('time (s)') plt.ylabel('Damped oscillation') with example(ui.line_plot): lines = ui.line_plot(n=2, limit=20, figsize=(2.5, 1.8)).with_legend(['sin', 'cos'], loc='upper center', ncol=2) line_updates = ui.timer(0.1, lambda: lines.push([datetime.now()], [ [np.sin(datetime.now().timestamp()) + 0.02 * np.random.randn()], [np.cos(datetime.now().timestamp()) + 0.02 * np.random.randn()], ]), active=False) ui.checkbox('active').bind_value(line_updates.active) with example(ui.joystick): ui.joystick( color='blue', size=50, on_move=lambda msg: coordinates.set_text(f'{msg.data.vector.x:.3f}, {msg.data.vector.y:.3f}'), on_end=lambda _: coordinates.set_text('0, 0')) coordinates = ui.label('0, 0') with example(ui.dialog): with ui.dialog() as dialog: with ui.card(): ui.label('Hello world!') ui.button('Close', on_click=dialog.close) ui.button('Open dialog', on_click=dialog.open) lifecycle = '''### Lifecycle You can run a function or coroutine on startup as a parallel task by passing it to `ui.on_startup`. If NiceGui is shut down or restarted, the tasks will be automatically canceled (for example when you make a code change). You can also execute cleanup code with `ui.on_shutdown`. ''' with example(lifecycle): with ui.row() as row: ui.label('count:') count_label = ui.label('0') count = 0 async def counter(): global count while True: count_label.text = str(count) count += 1 await row.view.update() await asyncio.sleep(1) ui.on_startup(counter()) ui.run()