Как запускать функции с помощью кнопки plotly-da sh внутри вкладки в python? - PullRequest
0 голосов
/ 13 июля 2020

Я новичок в программировании, а также в программировании sh. У меня есть несколько вкладок на моей панели инструментов, и на каждой вкладке у меня есть поле ввода текста (int) и кнопка, которая запускает некоторые вычисления с использованием ввода.

В следующем сценарии, когда я выбираю вкладку, выполняется обратный вызов запускается, и расчет уже начинается с пустого значения в тексте даже до того, как я нажму кнопку. У меня есть предложение if, которое ничего не возвращает, когда поле ввода текста пусто. Но, похоже, это не работает. Он напрямую переходит к последнему предложению else. Как я могу это решить? Спасибо!

@app.callback(Output('PRINTOUTPUT', 'children'),
              [Input('create_button', 'n_clicks'),
              Input('selection_tabs', 'value')],
              [State('text-input', 'value')])

def xyz (clicks, selected_tab, textinput):    
    
    changed_id = [p['prop_id'] for p in dash.callback_context.triggered][0] #To determine if n_clicks is changed. 

      
    if 'create_button' not in changed_id:
        return ""

    elif 'create_button' in changed_id:           
        if textinput =="":  #Do nothing if button is clicked and input num is blank.            
            return "No input"
        
        else: 
            #Do some calculations based on the selected tab and input
             return "Successful"

Ответы [ 2 ]

0 голосов
/ 19 июля 2020

Если в вашем коде есть проблема, вероятно, она не в той части, которую вы вставили в вопрос. Я написал MWE вокруг предоставленного вами обратного вызова, и кажется, что он работает так, как вы намеревались:

MWE demo1

Improvements for the callback

  • The code below includes a bit improved callback
  • The prop_id attribute of the items in the list dash.callback_context.triggered is of the form component_id.component_property. Therefore, if you want to check whether it was 'create_button' that triggered the callback, you should compare against the part before the dot (or compare to 'create_button.n_clicks' directly).
  • Previously, only the first element in the list dash.callback_context.triggered was checked. You probably want to check against all the elements in the list, although in current version of dash it can only contain properties of single component: "is a length-1 list, unless two properties of a single component update simultaneously, such as a value and a timestamp or event counter." ( da sh .callback_context.triggered )
  • Повышенная читаемость за счет удаления ненужное вложение операторов if, поскольку выполнение функции не будет продолжено после return.

Полный код

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)


tab_div = html.Div(
    dcc.Tabs(id='selection_tabs', value='tab-1', children=[
        dcc.Tab(label='Tab one', value='tab-1'),
        dcc.Tab(label='Tab two', value='tab-2'),
]))

app.layout = html.Div(children=[
    html.H1(children='Test app'),
    tab_div,
    dcc.Input(id="text-input", type="text", placeholder=""),
    html.Div(id='PRINTOUTPUT'),
    html.Button('Click me', id='create_button')
])

@app.callback(Output('PRINTOUTPUT', 'children'),
              [Input('create_button', 'n_clicks'),
              Input('selection_tabs', 'value')],
              [State('text-input', 'value')])

def xyz(clicks, selected_tab, textinput):    

    #To determine if n_clicks is changed. 
    changed_ids = [p['prop_id'].split('.')[0] for p in dash.callback_context.triggered]
    button_pressed = 'create_button' in changed_ids

    if not button_pressed:
        return ""

    if textinput == "":  #Do nothing if button is clicked and input num is blank.            
        return "No input"
    
    #Do some calculations based on the selected tab and input
    return "Successful"

if __name__ == '__main__':
    app.run_server(debug=True)
0 голосов
/ 19 июля 2020

Предполагая, что вы используете компонент dcc.Input для ввода текста, он имеет необязательный параметр value, который можно установить при его определении. По умолчанию это значение установлено на python s None. Поэтому, если вы не устанавливаете значение этого параметра как пустую строку "" при его определении, то сравнение его с "" в вашем предложении if приведет к False, и поэтому он всегда заканчивается в * Предложение 1008 *.

Вам просто нужно проверить, является ли ваш текстовый ввод None. Попробуйте изменить предложение if на if textinput is None: #Do nothing if button is clicked and input num is blank. Или вы также можете явно установить значение по умолчанию для вашего поля ввода на "" в том месте, где вы его определяете, но это кажется немного нелогичным.

...