提问人:Quastiat 提问时间:9/5/2023 最后编辑:Quastiat 更新时间:9/6/2023 访问量:62
Python Dash:如何使用来自动态创建的下拉列表的输入?
Python Dash: How to use Input from a dynamically created Dropdown?
问:
我有一个应用程序,其中包含一个带有回调功能的按钮,用于创建无限数量的下拉列表,这些下拉列表将自动标识为“dropdown-i”。 困难在于,我似乎无法在另一个回调函数(只是尝试打印它们)中实际使用我在这些下拉列表中输入的值。
如何检索这些值或如何执行此操作?
显然该部分不起作用。value=dcc.Dropdown(id=dropdown_id).value
import dash
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
app = dash.Dash(__name__)
app.layout = html.Div([
html.Button("Add Dropdown and Number Field", id="add-button"),
html.Div(id="input-container", children=[]),
html.Div(id="output"),
])
@app.callback(
Output("input-container", "children"),
Input("add-button", "n_clicks"),
State("input-container", "children")
)
def add_input(n_clicks, existing_children):
if n_clicks is None:
return existing_children
new_input = dbc.Row([
dbc.Col(dcc.Dropdown(
options=[
{'label': 'Option 1', 'value': 'option-1'},
{'label': 'Option 2', 'value': 'option-2'},
# Add more dropdown options as needed
],
value='option-1',
id=f'dropdown-{n_clicks}'
)),
dbc.Col(dcc.Input(
type='number',
value=0,
id=f'weight-{n_clicks}'
)),
])
existing_children.append(new_input)
return existing_children
@app.callback(
Output("output", "children"),
Input("add-button", "n_clicks"),
State("input-container", "children")
)
def process_dropdowns(n_clicks, dropdown_children):
if n_clicks is None:
return []
# Create a list to store the selected values from each dropdown
selected_values = []
# Iterate through the dropdowns to retrieve their values
for i, child in enumerate(dropdown_children):
dropdown_id = f'dropdown-{i+1}'
selected_value = dcc.Dropdown(id=dropdown_id).value
selected_values.append(selected_value)
# Process the selected values or use them as needed
return f"Selected Dropdown Values: {', '.join(selected_values)}"
if __name__ == "__main__":
app.run_server(debug=False)
答:
3赞
EricLavault
9/6/2023
#1
这是利用模式匹配回调选择器的典型用例。
模式匹配回调选择器 , , & 允许 您可以编写响应或更新任意或 组件的动态数量。
MATCH
ALL
ALLSMALLER
这个想法是使用字典而不是字符串来使用复合 id(类型+索引),这样我们就可以将给定组件识别为特定类型的第 n 个组件。
我还更新了第一个回调,以便它进行部分属性更新,而不是通过网络来回发送所有数据,这使其效率更高。
from dash import Dash, dcc, html, Input, Output, ALL, Patch, callback, no_update
import dash_bootstrap_components as dbc
app = Dash(__name__)
app.layout = html.Div([
html.Button("Add Dropdown and Number Field", id="add-button"),
html.Div(id="input-container", children=[]),
html.Div(id="output"),
])
@app.callback(
Output("input-container", "children"),
Input("add-button", "n_clicks")
)
def add_input(n_clicks):
if n_clicks is None:
return no_update
patched_children = Patch()
new_input = dbc.Row([
dbc.Col(dcc.Dropdown(
id={'type': 'dropdown', 'index': n_clicks},
options=[
{'label': 'Option 1', 'value': 'option-1'},
{'label': 'Option 2', 'value': 'option-2'},
# Add more dropdown options as needed
],
value='option-1',
)),
dbc.Col(dcc.Input(
id={'type': 'weight', 'index': n_clicks},
type='number',
value=0,
)),
])
patched_children.append(new_input)
return patched_children
@callback(
Output("output", "children"),
Input({"type": "dropdown", "index": ALL}, "value"),
)
def process_dropdowns(values):
return html.Div(
['Selected Dropdown Values:'] +
[html.Div(f"Dropdown {i + 1} = {value}") for (i, value) in enumerate(values)]
)
if __name__ == "__main__":
app.run_server(debug=False)
评论
0赞
Quastiat
9/8/2023
非常感谢,这似乎真的是我想要的。但它似乎只出现在 Dash 2.9 中,我无法超过 2.7。有什么诀窍吗?
1赞
EricLavault
9/8/2023
在 Dash 1.11.0 中添加了模式匹配 ID 和回调。但是,在 Dash 2.9 中添加了部分属性更新,因此在第一个回调中,您将无法使用 Patch 类,而必须使用 State 并从中重新构建输出,就像您最初所做的那样。从我的示例中(在第一个回调中)中,您唯一需要保留的是复合 ID,例如。,需要使第二个回调工作。id={'type': 'dropdown', 'index': n_clicks}
0赞
Quastiat
9/8/2023
真棒!非常感谢,这已经有效了!只是这种不同类型的ID打开了很多门,不知道这一点。
评论