Without going into the motivational details, I want to perform the following sequence of step using Panel:
Steps 1 and 2 work fine, but I can't get the 3rd thing to happen. Here is a minimum example that illustrates the problem when it is run:
import panel as pn
pn.extension()
# Create and organize basic elements to show where things go
file_input = pn.widgets.FileInput()
item_selector = pn.widgets.MultiSelect()
controls = pn.Column(file_input, "layout[0][1]")
layout = pn.Row(controls, pn.Column("layout[1][0]"))
print(layout)
# Set up selector object
@pn.depends(file_contents=file_input, watch=True)
def _item_selector(file_contents):
# Dummy items for illustration purpose
items = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
item_selector = pn.widgets.MultiSelect(
name="Choose items",
options=items,
size=12,
width=120,
value=items[:2],
)
layout[0][1] = item_selector
# Define interactivity based on selector object
@pn.depends(selected_items=item_selector, watch=True)
def _col(selected_items):
col = pn.Column()
for item in selected_items:
col.append(item)
layout[1] = col
layout
Any pointers to help clear up my misunderstandings would be much appreciated.
I figured out where I went wrong. In the function _item_selector()
I set layout[0][1]
to a new MultiSelect object, and the function _col()
is affected by the original MultiSelect object set up on line 6. The code below fixes the problem
import panel as pn
pn.extension()
# Create and organize basic elements to show where things go
file_input = pn.widgets.FileInput()
item_selector = pn.widgets.MultiSelect()
controls = pn.Column(file_input, "")
layout = pn.Row(controls, pn.Column(""))
# Set up selector object
@pn.depends(file_contents=file_input, watch=True)
def _item_selector(file_contents):
# Dummy file contents
items = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
item_selector.options = items
item_selector.value = ['a', 'c']
item_selector.size = 12
item_selector.width = 120
layout[0][1] = item_selector
# Define interactivity based on selector object
@pn.depends(selected_items=item_selector, watch=True)
def _col(selected_items):
col = pn.Column()
for item in selected_items:
col.append(item)
layout[1] = col
layout
I'm sure this is not the most elegant approach to the problem I am trying to solve, and I would be interested in any feedback. In particular, as a newbie to Panel, I don't know that it is necessary to set up the layout beforehand on lines 5-8, or if this can be done dynamically as well.