Преглед на файлове

Add new example with global computation and progress bar (#2685)

* create new example with global computation and progress bar

* renaming, integration
Falko Schindler преди 1 година
родител
ревизия
9f3911d327
променени са 2 файла, в които са добавени 65 реда и са изтрити 0 реда
  1. 64 0
      examples/global_worker/main.py
  2. 1 0
      website/examples.py

+ 64 - 0
examples/global_worker/main.py

@@ -0,0 +1,64 @@
+#!/usr/bin/env python3
+import asyncio
+import time
+from multiprocessing import Manager
+from queue import Empty, Queue
+from typing import Callable, Generator
+
+from nicegui import app, background_tasks, run, ui
+
+
+class Worker:
+
+    def __init__(self) -> None:
+        self._queue: Queue
+        self.progress: float = 0.0
+        self.is_running: bool = False
+
+        app.on_startup(self._create_queue)
+
+    async def run(self, func: Callable[..., Generator[float, None, None]]) -> None:
+        background_tasks.create(run.cpu_bound(self._run_generator, func, self._queue))
+        background_tasks.create(self._consume_queue())
+
+    @staticmethod
+    def _run_generator(func: Callable[..., Generator[float, None, None]], queue: Queue) -> None:
+        for progress in func():
+            queue.put({'progress': progress})
+        queue.put({'progress': 1.0})
+
+    def _create_queue(self) -> None:
+        self._queue = Manager().Queue()
+
+    async def _consume_queue(self) -> None:
+        self.is_running = True
+        self.progress = 0.0
+        while self.progress < 1.0:
+            try:
+                msg = self._queue.get_nowait()
+            except Empty:
+                await asyncio.sleep(0.1)
+                continue
+            self.progress = msg['progress']
+        self.is_running = False
+
+
+def heavy_computation() -> Generator[float, None, None]:
+    n = 50
+    for i in range(n):
+        time.sleep(0.1)
+        yield i / n
+
+
+worker = Worker()
+
+
+@ui.page('/')
+def main_page():
+    ui.button('compute', on_click=lambda: worker.run(heavy_computation))
+    ui.linear_progress().props('instant-feedback') \
+        .bind_value_from(worker, 'progress') \
+        .bind_visibility_from(worker, 'is_running')
+
+
+ui.run()

+ 1 - 0
website/examples.py

@@ -33,6 +33,7 @@ examples: List[Example] = [
     Example('OpenCV Webcam', 'uses OpenCV to capture images from a webcam'),
     Example('OpenCV Webcam', 'uses OpenCV to capture images from a webcam'),
     Example('SVG Clock', 'displays an analog clock by updating an SVG with `ui.timer`'),
     Example('SVG Clock', 'displays an analog clock by updating an SVG with `ui.timer`'),
     Example('Progress', 'demonstrates a progress bar for heavy computations'),
     Example('Progress', 'demonstrates a progress bar for heavy computations'),
+    Example('Global Worker', 'demonstrates a global worker for heavy computations with progress feedback'),
     Example('NGINX Subpath', 'shows the setup to serve an app behind a reverse proxy subpath'),
     Example('NGINX Subpath', 'shows the setup to serve an app behind a reverse proxy subpath'),
     Example('Script Executor', 'executes scripts on selection and displays the output'),
     Example('Script Executor', 'executes scripts on selection and displays the output'),
     Example('Local File Picker', 'demonstrates a dialog for selecting files locally on the server'),
     Example('Local File Picker', 'demonstrates a dialog for selecting files locally on the server'),