From d239645c03e2f435d48a5bdf80e215c503d8894a Mon Sep 17 00:00:00 2001 From: Rodja Trappe Date: Fri, 8 Sep 2023 06:09:36 +0200 Subject: [PATCH 1/2] example: custom binding --- examples/custom_binding/main.py | 41 +++++++++++++++++++++++++++++++++ main.py | 1 + 2 files changed, 42 insertions(+) create mode 100755 examples/custom_binding/main.py diff --git a/examples/custom_binding/main.py b/examples/custom_binding/main.py new file mode 100755 index 000000000..87bb7779e --- /dev/null +++ b/examples/custom_binding/main.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 + +import random + +from nicegui import ui +from nicegui.binding import BindableProperty, bind_from + + +class colorful_label(ui.label): + """A label with a bindable background color.""" + + # this class variable defines what happens when the background property changes + background = BindableProperty(on_change=lambda sender, bg: sender.on_background_change(bg)) + + def __init__(self, text: str): + super().__init__(text) + self.background = None # initialize the background property + + def on_background_change(self, bg: str) -> None: + """Update the classes of the label when the background property changes.""" + self._classes = [c for c in self._classes if not c.startswith('bg-')] + self._classes.append(bg) + self.update() + + +def shuffle(): + for key in data: + data[key] = random.choice([True, False]) + + +ui.button('shuffle', on_click=shuffle) +data = {} +for k in 'abcde': + data[k] = random.choice([True, False]) + label = colorful_label(k.upper()).classes('w-48 text-center') + # binding from the data to the label + # there is also a bind_to method which would propagate changes from the label to the data + # and a bind method which would propagate changes both ways + bind_from(label, 'background', data, k, backward=lambda x: 'bg-green' if x else 'bg-red') + +ui.run() diff --git a/main.py b/main.py index bc6e7e7d1..dccd360a6 100755 --- a/main.py +++ b/main.py @@ -349,6 +349,7 @@ async def index_page(client: Client) -> None: '[zauberzeug/nicegui](https://hub.docker.com/r/zauberzeug/nicegui) docker image') example_link('Download Text as File', 'providing in-memory data like strings as file download') example_link('Generate PDF', 'create SVG preview and PDF download from input form elements') + example_link('Custom Binding', 'create a custom binding for a label with a bindable background color') with ui.row().classes('dark-box min-h-screen mt-16'): link_target('why') From 43eb62e8b45402eb3a0117e62f4e1fe381ea5b0d Mon Sep 17 00:00:00 2001 From: Falko Schindler Date: Sat, 16 Sep 2023 22:06:11 +0200 Subject: [PATCH 2/2] code review and overall improvements(?) --- examples/custom_binding/main.py | 37 ++++++++++++++++----------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/examples/custom_binding/main.py b/examples/custom_binding/main.py index 87bb7779e..0d2a5c777 100755 --- a/examples/custom_binding/main.py +++ b/examples/custom_binding/main.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 - import random +from typing import Optional from nicegui import ui from nicegui.binding import BindableProperty, bind_from @@ -9,33 +9,32 @@ class colorful_label(ui.label): """A label with a bindable background color.""" - # this class variable defines what happens when the background property changes - background = BindableProperty(on_change=lambda sender, bg: sender.on_background_change(bg)) + # This class variable defines what happens when the background property changes. + background = BindableProperty(on_change=lambda sender, value: sender.on_background_change(value)) - def __init__(self, text: str): + def __init__(self, text: str = '') -> None: super().__init__(text) - self.background = None # initialize the background property + self.background: Optional[str] = None # initialize the background property - def on_background_change(self, bg: str) -> None: + def on_background_change(self, bg_class: str) -> None: """Update the classes of the label when the background property changes.""" self._classes = [c for c in self._classes if not c.startswith('bg-')] - self._classes.append(bg) + self._classes.append(bg_class) self.update() -def shuffle(): - for key in data: - data[key] = random.choice([True, False]) +temperatures = {'Berlin': 5, 'New York': 15, 'Tokio': 25} +ui.button(icon='refresh', on_click=lambda: temperatures.update({city: random.randint(0, 30) for city in temperatures})) -ui.button('shuffle', on_click=shuffle) -data = {} -for k in 'abcde': - data[k] = random.choice([True, False]) - label = colorful_label(k.upper()).classes('w-48 text-center') - # binding from the data to the label - # there is also a bind_to method which would propagate changes from the label to the data - # and a bind method which would propagate changes both ways - bind_from(label, 'background', data, k, backward=lambda x: 'bg-green' if x else 'bg-red') +for city in temperatures: + label = colorful_label().classes('w-48 text-center') \ + .bind_text_from(temperatures, city, backward=lambda t, city=city: f'{city} ({t}°C)') + # Bind background color from temperature. + # There is also a bind_to method which would propagate changes from the label to the temperatures dictionary + # and a bind method which would propagate changes both ways. + bind_from(self_obj=label, self_name='background', + other_obj=temperatures, other_name=city, + backward=lambda t: 'bg-green' if t < 10 else 'bg-yellow' if t < 20 else 'bg-orange') ui.run()