我有一个打印随机值的函数。 当按下按钮
Start
时,该功能被“激活”。
print("acquisition is on")
print(random.random())
此时控制台中会打印随机值。但我想知道如何直接在html.Div中输出这个值。
以下是完整代码
from dash import Dash, html, dcc, Input, Output, ctx
import dash_bootstrap_components as dbc
import time
import threading
import random
app = Dash(
__name__,
external_stylesheets = [dbc.themes.SPACELAB, dbc.icons.FONT_AWESOME],
title = 'MT',
prevent_initial_callbacks = "initial_duplicate"
)
class Nanotec(threading.Thread):
def __init__(self, *args, **kwargs):
# When Main is excuted, this does :
super(Nanotec, self).__init__(*args, **kwargs)
self.__flag = threading.Event() # The flag used to pause the thread
self.__flag.set() # Set to True
self.__running = threading.Event() # Used to stop the thread identification
self.__running.set() # Set running to True
def run(self):
while self.__running.isSet():
self.__flag.wait() # return immediately when it is True, block until the internal flag is True when it is False
print("acquisition is on")
print(random.random())
time.sleep(1)
def pause(self):
self.__flag.clear() # Set to False to block the thread
print("pausing")
def resume(self):
self.__flag.set() # Set to True, let the thread stop blocking
print("resuming")
def stop(self):
self.__flag.set() # Resume the thread from the suspended state, if it is already suspended
self.__running.clear() # Set to False
@app.callback(Output('container', 'children'),
Input('btn_start_nanotec', 'n_clicks'),
Input('btn_pause_nanotec', 'n_clicks'),
Input('btn_resume_nanotec', 'n_clicks')
)
def display(btn_start_nanotec, btn_pause_nanotec, btn_resume_nanotec):
button_id = ctx.triggered_id if not None else 'No clicks yet'
if button_id == "btn_start_nanotec" :
my_thread_nanotec.start()
elif button_id == "btn_pause_nanotec" :
my_thread_nanotec.pause()
elif button_id == "btn_resume_nanotec" :
my_thread_nanotec.resume()
my_thread_nanotec = Nanotec()
app.layout = html.Div([
html.Button('Start', id='btn_start_nanotec'),
html.Button('Pause', id='btn_pause_nanotec'),
html.Button('Resume', id='btn_resume_nanotec'),
html.Div(id='container'),
html.Br(),
])
if __name__ == "__main__":
app.run_server(debug = True)
我不太确定你想在这里对多线程类做什么。它应该每秒更新一次
html.Div
吗?单击按钮时文本是否应该更新?
但是由于问题是“如何赋值……”,这里有一个快速解释。我用一个简单的生成器替换了多线程类,以使事情变得更清晰。 您的回调应该返回要放入
html.Div
的值。所以这里的值是从生成器中获取的(当单击按钮时)并返回:
import random
from dash import Dash, html, dcc, Input, Output, ctx
app = Dash(__name__, title="MT", prevent_initial_callbacks="initial_duplicate")
def randoms():
while True:
yield random.random()
random_iter = randoms()
@app.callback(
Output(component_id="container", component_property="children"),
Input("btn_start_nanotec", "n_clicks"),
Input("btn_pause_nanotec", "n_clicks"),
Input("btn_resume_nanotec", "n_clicks"),
)
def display(*_):
button_id = ctx.triggered_id
if button_id == "btn_start_nanotec":
result = next(random_iter)
elif button_id == "btn_pause_nanotec":
result = 'Pause?..'
elif button_id == "btn_resume_nanotec":
result = next(random_iter)
return result
app.layout = html.Div(
[
html.Button("Start", id="btn_start_nanotec"),
html.Button("Pause", id="btn_pause_nanotec"),
html.Button("Resume", id="btn_resume_nanotec"),
html.Div(id="container"),
html.Br(),
]
)
if __name__ == "__main__":
app.run_server(debug=True)
您可以将我的超级简单迭代器替换为其他任何东西(
threading.Thread
,multiprocessing.Pool
,等等),但回调仍然必须从源获取值并返回它。
如果您需要定期更新输出(每秒一次),请查看Intervals。相同的基本原理是一样的(回调返回值),但它会为您处理定期更新。
Websocket
组件似乎非常适合这个要求:数据由另一个进程/线程发送并(某种程度上)实时更新,甚至支持双向通信(暂停/恢复)。