main.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #!/usr/bin/env python3
  2. from dataclasses import dataclass, field
  3. from typing import Callable, List
  4. from nicegui import ui
  5. @dataclass
  6. class TodoItem:
  7. name: str
  8. done: bool = False
  9. @dataclass
  10. class ToDoList:
  11. title: str
  12. on_change: Callable
  13. items: List[TodoItem] = field(default_factory=list)
  14. def add(self, name: str, done: bool = False) -> None:
  15. self.items.append(TodoItem(name, done))
  16. self.on_change()
  17. def remove(self, item: TodoItem) -> None:
  18. self.items.remove(item)
  19. self.on_change()
  20. @ui.refreshable
  21. def todo_ui():
  22. if not todos.items:
  23. ui.label('List is empty.').classes('mx-auto')
  24. return
  25. ui.linear_progress(sum(item.done for item in todos.items) / len(todos.items), show_value=False)
  26. with ui.row().classes('justify-center w-full'):
  27. ui.label(f'Completed: {sum(item.done for item in todos.items)}')
  28. ui.label(f'Remaining: {sum(not item.done for item in todos.items)}')
  29. for item in todos.items:
  30. with ui.row().classes('items-center'):
  31. ui.checkbox(value=item.done, on_change=todo_ui.refresh).bind_value(item, 'done') \
  32. .mark(f'checkbox-{item.name.lower().replace(" ", "-")}')
  33. ui.input(value=item.name).classes('flex-grow').bind_value(item, 'name')
  34. ui.button(on_click=lambda item=item: todos.remove(item), icon='delete').props('flat fab-mini color=grey')
  35. todos = ToDoList('My Weekend', on_change=todo_ui.refresh)
  36. todos.add('Order pizza', done=True)
  37. todos.add('New NiceGUI Release')
  38. todos.add('Clean the house')
  39. todos.add('Call mom')
  40. with ui.card().classes('w-80 items-stretch'):
  41. ui.label().bind_text_from(todos, 'title').classes('text-semibold text-2xl')
  42. todo_ui()
  43. add_input = ui.input('New item').classes('mx-12').mark('new-item')
  44. add_input.on('keydown.enter', lambda: todos.add(add_input.value))
  45. add_input.on('keydown.enter', lambda: add_input.set_value(''))
  46. if __name__ in {'__main__', '__mp_main__'}:
  47. ui.run()