Hi everyone.
I am trying to set a watcher of a param of an underlying object of my class. I have provided code for the implementation but the idea is pretty simple:
class Styler
def __init__:
self.spin = 2
class Dashboard:
styler=Styler()
@param.depends('styler.spin', watch=True)
def watch_spin
This is the general idea. How can I set up a watcher of this subobject ? And is it even possible ?
Here is the full exemple using the wonderful LoadingSpinner exemple provided in Awesome-Panels.
import random
import time
import holoviews as hv
import panel as pn
import param
from awesome_panel_extensions.site import site
from panel.io.loading import start_loading_spinner, stop_loading_spinner
from application.utils import config_spinner as config
hv.extension("bokeh")
class LoadingStyler(param.Parameterized):
"""A utility that can be used to select and style the loading spinner"""
spinner_height = param.Integer(50, bounds=(1, 100))
settings_panel = param.Parameter(doc="A panel containing the settings of the LoadingStyler")
def __init__(self, **params):
super().__init__(**params)
self.settings_panel = pn.Param(
self,
parameters=[
"spinner_height",
],
)
self._update_style()
@param.depends(
"spinner_height", watch=True
)
def _update_style(self):
print(self.spinner_height)
class LoadingApp(param.Parameterized): # pylint: disable=too-many-instance-attributes
"""An app which show cases the loading spinner and enables the user to style it."""
start_loading = param.Action(label="START LOADING", doc="Start the loading spinner")
panels = param.List()
view = param.Parameter()
styler = param.ClassSelector(class_=LoadingStyler)
def __init__(self, **params):
super().__init__(**params)
self.start_loading = self._start_loading
self.stop_loading = self._stop_loading
self.update_plot = self._update_plot
hv_plot = self._get_plot()
self.hv_plot_panel = pn.pane.HoloViews(hv_plot, min_height=300, sizing_mode="stretch_both")
self.styler = LoadingStyler(name="Styles")
self.panels = [
self.hv_plot_panel,
]
self.settings_panel = pn.Column(
pn.pane.Markdown("## Settings"),
pn.Param(
self,
parameters=[
"start_loading",
],
show_name=False,
),
self.styler.settings_panel,
sizing_mode="stretch_width",
)
self.main = pn.Column(*self.panels, sizing_mode="stretch_both")
self.view = pn.Row(self.settings_panel, self.main)
def _start_loading(self, *_):
self.loading = True
def _stop_loading(self, *_):
self.loading = False
@staticmethod
def _get_plot():
xxs = ["one", "two", "tree", "four", "five", "six"]
data = []
for item in xxs:
data.append((item, random.randint(0, 10)))
return hv.Bars(data, hv.Dimension("Car occupants"), "Count").opts(
height=500,
responsive=True,
color="red",
)
def _update_plot(self, *_):
self.loading = True
time.sleep(self.sleep)
self.hv_plot_panel.object = self._get_plot()
self.loading = False
def _start_loading_spinner(self, *_):
# Only nescessary in this demo app to be able to toggle show_shared_spinner
self._stop_loading_spinner()
if self.show_shared_spinner:
start_loading_spinner(self.main)
else:
for panel in self.panels:
start_loading_spinner(panel)
def _stop_loading_spinner(self, *_):
stop_loading_spinner(self.main)
for panel in self.panels:
stop_loading_spinner(panel)
# @param.depends(
# "styler.spinner_height", watch=True
# )
# def _update_style(self):
# print(self.spinner_height)
def view():
"""Returns the app in a Template"""
pn.config.sizing_mode = "stretch_width"
template = pn.template.FastListTemplate(title="Loading Spinners")
app = LoadingApp(name="Loading Spinner App")
template.sidebar[:] = [app.settings_panel]
template.main[:] = [app.main]
if not issubclass(template.theme, pn.template.base.DefaultTheme):
app.styler.background_rgb = (0, 0, 0)
return template
view().servable()