【问题标题】:Python Dash: Hide a component with one event and make it visible with another created through a callbackPython Dash:使用一个事件隐藏组件,并通过回调创建的另一个组件使其可见
【发布时间】:2019-02-09 14:00:23
【问题描述】:

这是我想用 Dash 做的一个“几乎”工作的例子。几乎是因为这段代码有效,但缺少我打算​​做的一部分,但是当我尝试实现另一部分时,我得到了一个错误。

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
app = dash.Dash()
app.config['suppress_callback_exceptions']=True
image = "tmpimg.png"

app.layout = html.Div([
       html.Div([
       html.Div([
           html.Button('Load image', id='load-button'),
           dcc.Upload(
                   id='upload-data',
                   children=html.Button('Upload image', id='upload-button')
           )
       ]),
       html.Div([
           html.Div(id='images-div'),
           html.Div(id='classification-div'),
           html.Div(id='classification-div2')
       ])
       ])
 ])

@app.callback(
   Output(component_id='images-div', component_property='children'),
   [Input('load-button','n_clicks')]
)
def update_output_div_img(n_clicks):
   return html.Div([html.Img(
                           src=app.get_asset_url(image),
                           style={
                                   'width' : '10%',
                                    'cursor': 'pointer'
                                   }
                       )], id='img'
                   )

@app.callback(
   Output(component_id='classification-div', component_property='children'),
   [Input('img','n_clicks')]
)
def update_output_div1(n_clicks):  
   return html.Div([html.H2('Div1')])

@app.callback(Output('classification-div2', 'children'),
             [Input('upload-data', 'contents')])
def update_output_div2(content):
   return html.Div([html.H2('Div2')])

@app.callback(
   Output(component_id='classification-div', component_property='style'),
   [Input('upload-data', 'contents')]
)
def update_style(content):
   if content:
       return {'display':'none'}
   else: return {'display':'inline'}


if __name__ == '__main__':
   app.run_server() 

当您加载页面或按下“加载图像”按钮时,update_output_div_img 将加载带有回调的图像。现在加载图像后,您可以单击它,然后会出现一个文本 Div1。当您按下上传按钮加载图像时,“Div1”应该会消失,只剩下 Div 2。到目前为止一切顺利。

现在,当我再次单击图像时,“Div1”文本不会出现,因为显示已更改为“无”。我希望当我再次单击图像时,“Div1”文本应该再次显示,所以我修改了上面第一个 div 样式的回调,以便在单击图像时触发它,因为没有内容我猜它应该将显示更改为内联。

@app.callback(
   Output(component_id='classification-div', component_property='style'),
   [Input('upload-data', 'contents'),
    Input('img','n_clicks')]
)
def update_style(content,n_clicks):
   if content:
       return {'display':'none'}
   else: return {'display':'inline'}

但这会在我加载网页时触发“加载依赖项错误”消息。我认为问题的发生是因为单击的图像是由另一个回调生成的,而上传组件是从一开始就加载的。

任何想法如何解决这个问题?

【问题讨论】:

    标签: python-3.x plotly-dash


    【解决方案1】:

    我不确定我是否正确理解了您想要实现的目标,但这里对您的代码进行了修复,以避免出现依赖项问题:

    import dash
    import dash_core_components as dcc
    import dash_html_components as html
    from dash.dependencies import Input, Output
    app = dash.Dash()
    app.config['suppress_callback_exceptions']=True
    image = "tmpimg.png"
    
    app.layout = html.Div([
           html.Div([
           html.Div([
               html.Button('Load image', id='load-button'),
               dcc.Upload(
                       id='upload-data',
                       children=html.Button('Upload image', id='upload-button')
               )
           ]),
           html.Div([
               html.Div([html.Div(id='img')], id='images-div'),
               html.Div(id='classification-div'),
               html.Div(id='classification-div2')
           ])
           ])
     ])
    
    @app.callback(
       Output(component_id='img', component_property='children'),
       [Input('load-button', 'n_clicks')]
    )
    def update_output_div_img(n_clicks):
        if n_clicks and n_clicks>0:
            return [html.Img(src=app.get_asset_url(image),
                                   style={
                                           'width' : '10%',
                                            'cursor': 'pointer'
                                           })]
    
    @app.callback(
       Output(component_id='classification-div', component_property='children'),
       [Input('img','n_clicks')]
    )
    def update_output_div1(n_clicks):
        if n_clicks and n_clicks>0:
            return [html.H2('Div1')]
    
    @app.callback(Output('classification-div2', 'children'),
                 [Input('upload-data', 'contents')])
    def update_output_div2(content):
        if content:
            return [html.H2('Div2')]
    
    @app.callback(
       Output(component_id='classification-div', component_property='style'),
       [Input('upload-data', 'contents'),
        Input('img','n_clicks')]
    )
    def update_style(content, n_clicks):
       if content and n_clicks and n_clicks>0:
           return {'display':'none'}
       else: return {'display':'inline'}
    
    
    if __name__ == '__main__':
       app.run_server()
    

    基本上,您的问题是您尝试使用 id=img 未在 app.layout 中定义的组件作为输入。 此外,如果您不希望在页面加载时触发这些回调,请考虑为所有按钮添加对 n_clicks 的检查。

    【讨论】:

      猜你喜欢
      • 2012-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-11
      • 2018-10-17
      • 1970-01-01
      相关资源
      最近更新 更多