如何在Python中动态切换Dash Bootstrap主题并刷新应用?
问题解答
核心结论
- 不能通过重新赋值
external_stylesheets或重新创建Dash实例的方式切换主题——该参数是应用初始化时加载的静态资源配置,运行时修改无法同步到前端。 - 无需刷新整个应用,Dash支持动态切换样式表,有两种简洁的实现方式。
可行实现方案
方案一:动态修改样式表链接(基础实现)
通过控制前端<link>标签的href属性,实时切换加载的主题样式表,无需重启应用:
import dash_bootstrap_components as dbc from dash import Dash, dcc, html, Input, Output import webbrowser as web ##### Constants ##### DASH_HOST = '127.0.0.1' DASH_PORT = 8020 DASH_URL = f'http://{DASH_HOST}:{DASH_PORT}' THEME_MENU_OPTIONS = { 'DARKLY': dbc.themes.DARKLY, 'LITERA': dbc.themes.LITERA, 'MORPH': dbc.themes.MORPH, 'QUARTZ': dbc.themes.QUARTZ, 'SLATE': dbc.themes.SLATE, 'SOLAR': dbc.themes.SOLAR } # 初始化应用,加载默认主题 app = Dash( title='Weather Forecast', external_stylesheets=[dbc.themes.DARKLY] ) app.layout = dbc.Card( [ html.H5(id='h5'), dcc.Dropdown( options=[{'label': k, 'value': v} for k, v in THEME_MENU_OPTIONS.items()], value=dbc.themes.DARKLY, clearable=False, id='theme_picker', style={"color": "black"} ), # 用于动态切换主题的样式表占位符 html.Link(id='dynamic-theme', rel='stylesheet', href=dbc.themes.DARKLY) ] ) @app.callback( [Output('h5', 'children'), Output('dynamic-theme', 'href')], Input('theme_picker', 'value'), ) def change_theme(value): # 返回当前主题URL,同时更新样式表链接 return value, value ##### Open app ##### web.open(DASH_URL, new=0, autoraise=True) if __name__ == '__main__': app.run(port=DASH_PORT, debug=True)
方案二:使用Dash Bootstrap Components内置工具(推荐)
利用dbc.ThemeSwitchAIO或dbc.ThemeChangerAIO组件,更简洁地实现主题切换,无需手动处理样式表标签:
import dash_bootstrap_components as dbc from dash import Dash, html import webbrowser as web ##### Constants ##### DASH_HOST = '127.0.0.1' DASH_PORT = 8020 DASH_URL = f'http://{DASH_HOST}:{DASH_PORT}' # 初始化应用,加载基础样式 app = Dash( title='Weather Forecast', external_stylesheets=[dbc.themes.DARKLY, dbc.icons.BOOTSTRAP] ) # 使用内置主题切换器 app.layout = dbc.Container([ html.H5("主题切换演示"), dbc.ThemeChangerAIO( aio_id="theme", radio_props={ "options": [ {"label": "Darkly", "value": dbc.themes.DARKLY}, {"label": "Litera", "value": dbc.themes.LITERA}, {"label": "Morph", "value": dbc.themes.MORPH}, {"label": "Quartz", "value": dbc.themes.QUARTZ}, {"label": "Slate", "value": dbc.themes.SLATE}, {"label": "Solar", "value": dbc.themes.SOLAR}, ], "value": dbc.themes.DARKLY, "inline": True } ) ]) ##### Open app ##### web.open(DASH_URL, new=0, autoraise=True) if __name__ == '__main__': app.run(port=DASH_PORT, debug=True)
关键原理说明
- 主题样式表本质是前端的
<link>资源,动态修改该标签的href属性即可实时切换主题,无需刷新整个应用。 - 不要尝试重新创建
Dash实例:运行中的应用已和前端建立WebSocket连接,重新实例化不会替换现有运行的应用,完全无效。
内容的提问来源于stack exchange,提问作者Tamer Gomaa
相关产品推荐
相关产品推荐

