Change widgets appearance when they are created from a Parameterized class?

This should be easy to figure out but I haven’t been able to:

How do I customize the appearance of widgets created with panel.Param from a param.Parameterized class?

Specifically, I’m looking to make the ListSelector taller to display more options at a time:

import panel as pn
import param

class Test(param.Parameterized):
    full_list = param.List([1,2,3])
    selected_list = param.ListSelector([1,2,3], objects=[1,2,3])

    @param.depends("full_list", watch=True)
    def _list_auditlogs_in_selection(self):
        self.param['selected_list'].objects = self.full_list
        self.selected_list = self.full_list

Now if I supply selected_list a height argument, the height of the other widget (for full_list) changes too.

t = Test()

pn.Param(t.param, widgets={
    'selected_list': {'height': 1000},
})


It also leaves a lot of space below the two widgets (I’m not using extra line breaks between the screenshot and this line of text).

What is the correct way of supplying arguments to change widget properties when they are created from a Parameterized class?

which version of panel are you using?
Your code give me this output:

2 Likes

Hey!
I have a similar issue, it seems that the pn.Param(…) it’s not being called/used in my case. I use VScode and .servable.

The could looks like this:

# panel serve test.py --autoreload --show
import param
import panel as pn

class test(param.Parameterized):
    select_downPay = param.Selector(objects=["A", "B"])

test_obj = test()

pn.Param(test_obj.param, widgets={
            'select_downPay': {'widget_type':pn.widgets.RadioButtonGroup},
            })

template = pn.template.FastGridTemplate(
    site="Panel", title="FastGridTemplate",
    sidebar=[test_obj.param
             ],
)
template.servable()

And I get like the image attached.

Also, is there a way to see the properties of the param. objects? like value, disabled, etc… and change them? such as disable a param. object?

Thank you!

1 Like

Hi @amoratoc

The issue is that its not the pn.Param object you show in the app. Its a separate test.param.select_downPay object.

This works

import param
import panel as pn

class test(param.Parameterized):
    select_downPay = param.Selector(objects=["A", "B"])

test_obj = test()

widgets = pn.Param(test_obj.param, widgets={
            'select_downPay': {'widget_type':pn.widgets.RadioButtonGroup},
            })

template = pn.template.FastGridTemplate(
    site="Panel", title="FastGridTemplate",
    sidebar=[widgets],
)
template.servable()

image

Regarding the second question about disabling. I would do it as below.

import param
import panel as pn

class test(param.Parameterized):
    select_downPay = param.Selector(objects=["A", "B"])

test_obj = test()

widget = pn.widgets.RadioButtonGroup.from_param(test_obj.param.select_downPay)

template = pn.template.FastGridTemplate(
    site="Panel", title="FastGridTemplate",
    sidebar=[widget, widget.param.disabled],
)
template.servable()

disable-widget

Thanks a lot @Marc!

What if you want to disable the widget in a method inside the class when a condition is met? (see code below)
I understand that when you define a class with param.Parameterized you can not use “pn.widgets” in it to enable/disable, right? (doing the .from_param)

# panel serve test.py --autoreload --show
import param
import panel as pn

class test(param.Parameterized):
    select_downPay = param.Selector(objects=["A", "B"])
    # select_downPay = pn.widgets.RadioButtonGroup.from_param(param.Selector(objects=["A", "B"]))
    num_box = param.Parameter(default=10)
    
    # @param.depends('select_downPay', watch=True)
    # def _disable_num_box(self):
    #     if self.select_downPay == 'A':
    #         Disalbe "self.num_box"

    #     if self.select_downPay == 'B':
    #         Enable "self.num_box"

test_obj = test()

widget = pn.Param(test_obj.param.select_downPay, widgets={
            'select_downPay': {'widget_type':pn.widgets.RadioButtonGroup},
            })

template = pn.template.FastGridTemplate(
    site="Panel", title="FastGridTemplate",
    sidebar=[widget, 
             test_obj.param.num_box]
    )
template.servable()

Thanks again!

You will need to set self.param.num_box.constant=True or False.

# panel serve test.py --autoreload --show
import param
import panel as pn

class test(param.Parameterized):
    select_downPay = param.Selector(objects=["A", "B"])
    # select_downPay = pn.widgets.RadioButtonGroup.from_param(param.Selector(objects=["A", "B"]))
    num_box = param.Parameter(default=10)
    
    @param.depends('select_downPay', watch=True, on_init=True)
    def _disable_num_box(self):
        if self.select_downPay == 'A':
            self.param.num_box.constant=True

        if self.select_downPay == 'B':
            self.param.num_box.constant=False

test_obj = test()

widget = pn.Param(test_obj.param.select_downPay, widgets={
            'select_downPay': {'widget_type':pn.widgets.RadioButtonGroup},
            })

template = pn.template.FastGridTemplate(
    site="Panel", title="FastGridTemplate",
    sidebar=[widget, 
             test_obj.param.num_box]
    )
template.servable()