Dash Python:布局函数中的 @Callback 未被调用

问题描述 投票:0回答:1

我有一个简单的数据框:

import pandas as pd
df = pd.DataFrame({'Class1': [1, 2, 3, 4, 5],
                   'Class2': [6, 7, 8, 9, 10]}
)  

我创建了一个数据提取函数,可以根据列的位置分割数据。

数据提取.py

def dataExtraction(arg1):

    df = pd.DataFrame({'Class1': [1, 2, 3, 4, 5],
                             'Class2': [6, 7, 8, 9, 10]})  ## <-- or Import df from somewhere
    df = df[[f'Class{arg1}']]

    return df    

布局.py

import dash_bootstrap_components as dbc
from dash import dcc, html, Input, Output, callback
from dash import Dash, dash_table, State
import dash_daq as daq
import pandas as pd

def update_page(arg1, arg2):
    layout = html.Div(children=[
        html.H1(f'Class {arg1}'),
        daq.NumericInput(
            id='numericinput1',
            min=0,
            max=100,
            value=0, ), 
        html.Br(),
        dash_table.DataTable(
            id='tableTest',
            data=arg2.to_dict('records'),
            columns=[{"name": i, "id": i} for i in arg2.columns]),
    ])

    return layout

@callback(
    Output('tableTest', 'data'),
    Input('numericinput1', 'value'),
    State('tableTest', 'data'),
)

def updateTableTest(x,data):

    data = pd.DataFrame(data)

    if x > 0:
        **print(data) # Indicator that shows callback is working**
    print("CALLBACK WORKING!!!")

        return data.to_dict('records')
    return data.to_dict('records')

我还构建了一个选项卡页面,如下所示,它由一个带有 2 个选项卡的页面组成。 tab_page 显示选项卡及其各自的数据列(例如,第 1 列的选项卡 1)。我已经编写了“打印(数据)”来检查布局函数中的回调是否正常工作。它适用于一个选项卡,但不适用于另一个选项卡。

tab_page.py

import layout as lay
import data_extraction as de
import dash_bootstrap_components as dbc
from dash import html, Dash
import dash

app = Dash()

dash.register_page(__name__, 
                   path='/tabs') 

def get_layout(position):
        df = de.dataExtraction(position)
        layout = lay.update_page(position, df)
        return layout


tab1_content = dbc.Card(
    dbc.CardBody(
        [
                **get_layout(1)#<--- CALLBACK NOT WORKING HERE The print(data) is NOT working**
        ]
    ),
    className="mt-1",
)

tab2_content = dbc.Card(
    dbc.CardBody(
        [
                get_layout(2) #<--- The print(data) is working
        ]
    ),
    className="mt-2",
)

layout = html.Div(children = [
    dbc.Tabs(
    [
        dbc.Tab(tab1_content, label="1",activeLabelClassName="text-success"),
        dbc.Tab(tab2_content, label="2",activeLabelClassName="text-success"),
    ]
)])


app.layout = [layout]

if __name__ == '__main__':
    app.run(debug=True)

布局中的回调适用于 get_layout(2),但不适用于 get_layout(1)。为什么它对一个有效,而对另一个无效?

python callback plotly plotly-dash
1个回答
0
投票

布局中存在重复 id 的问题。并且单个回调不能链接到具有相同 id 的两个对象:

修复 1 - 删除重复的 ID

# layout.py
def update_page(arg1, arg2):

    layout = html.Div(children=[
        html.H1(f'Class {arg1}'),
        daq.NumericInput(
            id=f"numericinput{arg1}",
            min=0,
            max=100,
            value=0, ), 
        html.Br(),
        dash_table.DataTable(
            id=f"tableTest{arg1}",
            data=arg2.to_dict('records'),
            columns=[{"name": i, "id": i} for i in arg2.columns]),
    ])

    return layout

修复 2 - 进行两次回调,每个表一个回调

# layout.py
def create_callback(i):

    @callback(
        Output(f'tableTest{i}', 'data'),
        Input(f'numericinput{i}', 'value'),
        State(f'tableTest{i}', 'data'),
    )
    def updateTableTest(x, data):

        data = pd.DataFrame(data)
        print(x)
        if x > 0:
            print(data) # Indicator that shows callback is working

            return data.to_dict('records')
        return data.to_dict('records')      
    
    return updateTableTest

修复 3 - 发起回调

# tab_page.py
...
# initiate callbacks:
app.layout = [layout]

lay.create_callback(1)
lay.create_callback(2)


if __name__ == '__main__':
    app.run(debug=True)
...
© www.soinside.com 2019 - 2024. All rights reserved.