Python Dash-同一回调函数中的动态和静态输入选项
我需要写一个回调函数,它将有一个动态输入组件和一个静态输入组件。但把它们放在一起是一个错误 这就是我到目前为止所做的-Python Dash-同一回调函数中的动态和静态输入选项,python,plotly,plotly-dash,Python,Plotly,Plotly Dash,我需要写一个回调函数,它将有一个动态输入组件和一个静态输入组件。但把它们放在一起是一个错误 这就是我到目前为止所做的- @app.callback( [Output("new_list", "children")], [ #Static Input Component Input("clear", "n_clicks"), #Dynamic Input Component
@app.callback(
[Output("new_list", "children")],
[
#Static Input Component
Input("clear", "n_clicks"),
#Dynamic Input Component
Input(str(i), "value") for i in item_list[['item3','item2','item1']].stack().groupby(level=0).agg(' '.join)
],
)
###########################################################
## Updated sample working code
import dash
import dash_html_components as html
import dash_bootstrap_components as dbc
from dash import callback_context
from dash.dependencies import Input, Output, State
import numpy as np
import pandas as pd
import dash_table as dt
item1 = ['A','A','B','B']
item2 = ["W","X","Y","Z"]
item3 = ["L",np.nan,'M','L']
item_list = pd.DataFrame(list(zip(item1,item2,item3)),columns=["item1","item2","item3"])
cat_list = item_list.item1.unique()
global itemlist
itemlist = pd.DataFrame( columns = ['item','qty'])
for item in item_list[['item3','item2','item1']].stack().groupby(level=0).agg(' '.join):
itemlist.loc[len(itemlist)] = (item,0)
def Add_item(data,data2):
print("BILLING: Add_item()")
item_list = dbc.Card(children = [
generate_item(data,data2),
dbc.Row([
dbc.Col([
dbc.Button(
html.H5("Cancel"), id="cancel", className="ml-auto", color = "danger"
)
]),
dbc.Col([
dbc.Button(
html.H5("Clear"), id="clear", className="ml-auto", color = "info"
)
]),
],style = {"width": "71rem"})
],
id="modal-body-newitem"
)
return item_list
def generate_item(item_list,itemlist):
buttons = html.Div(children =[
dbc.Row([
dbc.Button(
html.H5(str('+ ' + a)),
id= str(a),
className="mb-3",
color="primary",
block=True
),
dbc.Collapse([
dbc.Card([
dbc.Row([
dbc.Col([dbc.Button(html.H5(str('+ ' + b)),className="mb-3",color="info",block=True, disabled = True)],width = 10),
dbc.Col([dbc.Input(type="number", min=0, max=20, step=1,value = itemlist.loc[itemlist.item == b,'qty'],id = b )],width = 2)
]) for b in item_list.loc[item_list.item1== a, ('item3','item2','item1')].stack().groupby(level=0).agg(' '.join).sort_values()
#,dbc.Card(dbc.CardBody(str("This content is for " + a)))
],body = True, style = {"width": "71rem", "justify": "centre", "align": "centre"})
],id= str("collapse" + a))
]) for a in item_list.item1.unique()
])
return buttons
app = dash.Dash(__name__,external_stylesheets=[dbc.themes.CYBORG])
app.config.suppress_callback_exceptions = True
server = app.server
app.title="Test"
app.layout = html.Div([
dbc.Card(
dbc.CardBody(
[
html.H5("New Item", className="card-title"),
Add_item(item_list,itemlist),
html.Div(id = 'new_list')
]
)
)
])
#Item Ctegory List
@app.callback(
[Output(str("collapse" + i), "is_open") for i in cat_list],
[Input(str(i), "n_clicks") for i in cat_list]+
[Input("cancel", "n_clicks")])
def toggle_collapse_category_box(*args):
trigger = callback_context.triggered[0]
print("MYBIZZAPP:toggle_collapse_category_box: Call - "+str(callback_context.triggered))
if not callback_context.triggered or trigger["prop_id"].split(".")[0] == 'cancel':
print('MYBIZZAPP:toggle_collapse_category_box: Not Triggered/Cancel')
global isopn
isopn = [False] * len(cat_list)
else:
print('MYBIZZAPP:toggle_collapse_category_box: Triggered')
for i in range(len(cat_list)):
if cat_list[i] == trigger["prop_id"].split(".")[0]:
isopn[i] = not isopn[i]
return isopn
### Clear item list
@app.callback(
[Output(str(i), "value") for i in item_list[['item3','item2','item1']].stack().groupby(level=0).agg(' '.join)],
[Input("cancel", "n_clicks"),
Input("clear", "n_clicks")])
def clear_item_box(n2,n3):
trigger = callback_context.triggered[0]
print("MYBIZZAPP:clear_item_box: Call - "+str(callback_context.triggered))
if trigger["prop_id"].split(".")[0] == 'cancel':
print("MYBIZZAPP:clear_item_box: cancel order")
itemlist = pd.DataFrame( columns = ['item','qty'])
for item in item_list[['item3','item2','item1']].stack().groupby(level=0).agg(' '.join):
itemlist.loc[len(itemlist)] = (item,0)
elif trigger["prop_id"].split(".")[0] == 'clear':
print("MYBIZZAPP:clear_item_box: clear order")
return [0] * len(item_list)
#Menu item list
@app.callback(
[Output("new_list", "children")],
[Input(str(i), "value") for i in item_list[['item3','item2','item1']].stack().groupby(level=0).agg(' '.join)]+
[Input("clear", "n_clicks"),
Input("cancel", "n_clicks")])
def menu_item_list(*args):
trigger = callback_context.triggered[0]
print("MYBIZZAPP:menu_item_list: Call - "+str(callback_context.triggered))
print(trigger["prop_id"].split(".")[0])
if not callback_context.triggered :
print('MYBIZZAPP:menu_item_list: Not Triggered')
global itemlist
itemlist = pd.DataFrame( columns = ['item','qty'])
for item in item_list[['item3','item2','item1']].stack().groupby(level=0).agg(' '.join):
itemlist.loc[len(itemlist)] = (item,0)
else:
print('MYBIZZAPP:menu_item_list: Triggered')
itemlist.loc[itemlist.item == trigger["prop_id"].split(".")[0],'qty'] = trigger["value"]
if trigger["prop_id"].split(".")[0] == 'clear' or trigger["prop_id"].split(".")[0] == 'clear':
print('MYBIZZAPP:menu_item_list: Clear|Cancel')
itemlist['qty'] = 0
print('MYBIZZAPP:menu_item_list: Item List')
print(itemlist)
return ['Total items selected - ' + str(sum(itemlist.qty))]
if __name__ == '__main__':
app.run_server(debug=True)
如果我不提及静态输入组件,代码工作正常。但是我也需要静态组件
我试图解决的总体问题是——我有动态输入文本框,如果在其中任何一个框中输入了一个值,则需要对该值进行说明并将其作为表返回。此外,还有一个“清除”按钮。如果单击,所有值都应重新设置为默认预定义值
提前感谢您的帮助。感谢您更新此错误。此问题来自您的列表理解。当您添加第一个输入时,它会为理解创建无效语法。不过,这应该是可行的:
@app.callback(
[输出(“新列表”、“子项”)],
[
#静态输入组件
输入(“清除”、“不点击”),
] + [
#动态输入组件
在item_列表[['item3','item2','item1']]中为i输入(str(i),“value”)。stack().groupby(level=0)。agg(''.join)
],
)
您遇到的错误是什么?您在此处共享的第一个输入
没有本质上的错误。很抱歉回复太晚。因此,我使用spyder作为我的编辑器—当我包含静态组件时,动态输入的行会突出显示消息——“代码分析-无效语法(pyflakes E)”,在python命令提示符下,我得到这个错误消息——“File”E:\python\mybiz360\mybizapp.py”,第161行输入(str(I),“value”)作为项目列表中的I[['item3','item2','item1'].stack().groupby(level=0).agg(''.join)^SyntaxError:无效语法`谢谢。我不再收到错误。但是我也不能使用静态组件。当我单击触发静态组件的“清除”按钮时,什么都没有发生。我在回调print(触发器[“prop_id”]。split(“.”[0])中包含了一个打印选项
测试是否触发了“清除”组件,但未触发。对此有何建议?仅供参考-动态组件正在按预期工作。此输入(“清除”)正在另一个回调中使用,它正在按预期工作。但不是在此回调中。我已更新了一个工作代码供您参考。因此,当添加更多项目时,清除/取消不会清除完整列表。所有项目的“itemlist”应为Qty=0。当调用清除或取消链接时,我没有处理模式匹配的callbacks之前,将需要研究。由于我的初始问题已解决,我将此问题标记为已结束。