【问题标题】:Run python script when a button is clicked in dash在破折号中单击按钮时运行python脚本
【发布时间】:2021-03-30 16:02:31
【问题描述】:

我正在使用 python Dash 开发一个多页仪表板。在主页上,我创建了一个带有“提交”按钮的布局。因此,当用户选择选项并单击“提交”按钮时,它应该调用另一个 .py 脚本并在同一页面上显示该脚本。

Index.py 是主程序 Layout.py 有布局 new1.py 具有“提交按钮”的布局 new2.py 是点击提交按钮时需要显示的脚本

这是我在 new1.py 中声明按钮的代码

html.Button('Clear',id='clear_button', n_clicks=0,  style = { 'width' : '30%', 'margin-top': '15vw', "margin":"15px" ,'border-radius': '8px'}),
            

具有按钮回调的Index.py

@app.callback(
   dash.dependencies.Output('apply_button', 'children'),
   [dash.dependencies.Input('button', 'n_clicks')])
def run_script_onClick(n_clicks):
  
   if not n_clicks:
       raise PreventUpdate
       
       script_path = 'python new2.py'

      call(["python3", script_path])
    
       
   
      return output_content 

这是正确的吗?当我单击“应用”按钮时,什么也没有出现。我希望 new2.py 的输出显示在同一屏幕上。另外我应该在哪里给出回电声明。在 Index.py 还是在 new1.py 中?有人可以帮忙吗?

谢谢, 普拉塔普

【问题讨论】:

  • 您使用了output_content,但您从未创建它 - 所以您应该收到错误消息。也许你需要像output_content = call(...) 这样的东西,但也许最好是import 来自new2.py 的代码并像普通代码一样执行它——但它需要保持new2.py 中的代码正常运行
  • 也许 yoi 应该首先使用print() 来查看函数是否被执行以及你在变量中得到了什么。它被称为"print debuging"
  • 如果你使用script_path = 'python new2.py',那么最后你运行代码call(["python3", "python new2.py"])这是完全错误的。

标签: python html plotly-dash


【解决方案1】:

函数os.system() 直接在屏幕上发送文本(到控制台),它只返回error code(数字0 表示OK),因此您不能将此文本分配给变量或使用return 发送。如果你使用subprocess.call() 那么你有同样的问题。您需要模块 subprocess 的其他功能 - 即。 subprocess.run()subprocess.check_output()

在某些情况下,您可能需要使用 Python 的完整路径 - 即。当您在没有shell=True 的情况下运行它时。有时使用脚本的完整路径也很好,因为代码可能在不同的文件夹中运行,而不是您期望的 - 您可以检查 Current Working directoryprint( os.getcwd() )


这是我在 Linux 上的最小工作代码。

我删除了style,因为它在这个问题中并不重要,而且我不使用from ... import ... 来显示哪些命令来自subprocess,哪些来自dash

import dash
import dash_html_components as html
import subprocess

app = dash.Dash(__name__)

app.layout = html.Div(children=[
                       html.Div([            
                       html.Button('Apply', id='apply-button', n_clicks=0),
                       html.Div(id='output-container-button', children='Hit the button to update.')
                      ])
                ])                      
                
@app.callback(
    dash.dependencies.Output('output-container-button', 'children'),
    [dash.dependencies.Input('apply-button', 'n_clicks')])
def run_script_onClick(n_clicks):
    #print('[DEBUG] n_clicks:', n_clicks)
    
    if not n_clicks:
        #raise dash.exceptions.PreventUpdate
        return dash.no_update

    # without `shell` it needs list ['/full/path/python', 'script.py']           
    #result = subprocess.check_output( ['/usr/bin/python', 'script.py'] )  

    # with `shell` it needs string 'python script.py'
    result = subprocess.check_output('python script.py', shell=True)  

    # convert bytes to string
    result = result.decode()  
    
    return result
            
if __name__ == "__main__":
    app.run_server(port=8080, debug=True)

script.py

import datetime

print(datetime.datetime.now().strftime("%Y.%m.%d %H:%M:%S"))

编辑:

如果你想创建多页,那么你应该使用import 来加载代码,运行它并创建新的布局对象 - 就像在https://dash.plotly.com/urls中一样

使用subprocess,您只能创建带有 HTML 的字符串,但不能创建布局对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-15
    • 2017-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    相关资源
    最近更新 更多