OK I’m now doing this, I’m not sure if this is ‘correct’ but it works and I’m quite pleased with it. Turned out not to be that difficult.
class Colors(param.Parameterized):
num = param.Number(3, bounds=(0, None))
colors = param.List([])
color_defaults = ['#1930e0', '#eded0e', '#cc0c49']
def __init__(self, **param):
super(Colors, self).__init__(**param)
self.colors_col = pn.Column()
for _ in range(self.num):
self._add_color()
self.param.watch(self.color_callback, ['colors'])
def _add_color(self):
try:
default = self.color_defaults[len(self.colors_col)]
except IndexError:
default = '#FFFFFF'
self.colors.append(default)
widget = pn.widgets.ColorPicker(value=default)
self.colors_col.append(widget)
widget.param.watch(self.color_event, ['value'])
def _remove_color(self):
widget = self.colors_col.pop(-1)
self.colors.pop(-1)
[widget.param.unwatch(watcher) for watcher in widget.param._watchers]
del widget
@param.depends('num', watch=True)
def _update_colors(self):
while len(self.colors_col) != self.num:
if len(self.colors_col) > self.num:
self._remove_color()
elif len(self.colors_col) < self.num:
self._add_color()
self.param.trigger('colors')
def color_event(self, *events):
for event in events:
idx = list(self.colors_col).index(event.obj)
self.colors[idx] = event.new
self.param.trigger('colors')
print(self.colors)
def panel(self):
return pn.Column(pn.Param(self.param), self.colors_col)
def color_callback(self, events):
print(events)
c = Colors()
c.panel().servable()
I’ve tried to obliviate the widget that gets removed but not very successfully, if i make a weakref to the widget that still persists.
EDIT: Added a color list that holds the colors. I trigger it manually because assigning elements doenst trigger it. It works well but the field showing the value of the list doesnt uptake (although I dont need this atm)