Динамическое обновление макета панели Holoviz - PullRequest
0 голосов
/ 20 июня 2020

Не вдаваясь в мотивационные подробности, я хочу выполнить следующую последовательность шагов с помощью Panel:

  1. Показать элемент panel.widgets.FileInput.
  2. После того, как файл будет был выбран, затем отобразите элемент panel.widgets.MultiSelect с элементами из файла, первые несколько из которых выбраны. Элемент MultiSelect отображается под элементом FileInput.
  3. В зависимости от того, что выбрано (как изначально, так и посредством взаимодействия пользователя с элементом panel.widgets.MultiSelect), отобразите некоторые элементы в столбце справа от Элемент FileInput.

Шаги 1 и 2 работают нормально, но я не могу выполнить третье действие. Вот минимальный пример, который иллюстрирует проблему при запуске:

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

Любые указатели, которые помогут прояснить мои недоразумения, будут очень признательны.

1 Ответ

1 голос
/ 20 июня 2020

Я понял, где ошибся. В функции _item_selector() я установил layout[0][1] на новый объект MultiSelect, а на функцию _col() влияет исходный объект MultiSelect, установленный в строке 6. Приведенный ниже код устраняет проблему

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

Я уверен, что это не самый элегантный подход к проблеме, которую я пытаюсь решить, и мне были бы интересны любые отзывы. В частности, как новичок ie в Panel, я не знаю, необходимо ли заранее настроить макет в строках 5-8, или можно ли это сделать также динамически.

...