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之前,将需要研究。由于我的初始问题已解决,我将此问题标记为已结束。