dcc.Tabs
#
参考:tabs
dcc.Tabs
和 dcc.Tab
组件可以用来在应用中创建选项卡式区域。dcc.Tab
组件控制单个选项卡的样式和值,而 dcc.Tabs
组件则包含一组 dcc.Tab
组件。
方法 1. 内容作为回调#
将回调附加到 Tabs 的 value
属性,并在回调中更新容器的 children
属性。
from dash import Dash, dcc, html, Input, Output, callback
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
html.H1('Dash Tabs component demo'),
dcc.Tabs(id="tabs-example-graph", value='tab-1-example-graph', children=[
dcc.Tab(label='Tab One', value='tab-1-example-graph'),
dcc.Tab(label='Tab Two', value='tab-2-example-graph'),
]),
html.Div(id='tabs-content-example-graph')
])
@callback(Output('tabs-content-example-graph', 'children'),
Input('tabs-example-graph', 'value'))
def render_content(tab):
if tab == 'tab-1-example-graph':
return html.Div([
html.H3('Tab content 1'),
dcc.Graph(
figure={
'data': [{
'x': [1, 2, 3],
'y': [3, 1, 2],
'type': 'bar'
}]
}
)
])
elif tab == 'tab-2-example-graph':
return html.Div([
html.H3('Tab content 2'),
dcc.Graph(
id='graph-2-tabs-dcc',
figure={
'data': [{
'x': [1, 2, 3],
'y': [5, 10, 6],
'type': 'bar'
}]
}
)
])
# if __name__ == '__main__':
# app.run(debug=True)
方法 2. 内容作为选项卡子项#
除了通过回调显示内容外,您还可以将内容直接嵌入到 Tab
组件的 children
属性中:
from dash import Dash, dcc, html
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
dcc.Tabs([
dcc.Tab(label='Tab one', children=[
dcc.Graph(
figure={
'data': [
{'x': [1, 2, 3], 'y': [4, 1, 2],
'type': 'bar', 'name': 'SF'},
{'x': [1, 2, 3], 'y': [2, 4, 5],
'type': 'bar', 'name': 'Montréal'},
]
}
)
]),
dcc.Tab(label='Tab two', children=[
dcc.Graph(
figure={
'data': [
{'x': [1, 2, 3], 'y': [1, 4, 1],
'type': 'bar', 'name': 'SF'},
{'x': [1, 2, 3], 'y': [1, 2, 3],
'type': 'bar', 'name': 'Montréal'},
]
}
)
]),
dcc.Tab(label='Tab three', children=[
dcc.Graph(
figure={
'data': [
{'x': [1, 2, 3], 'y': [2, 4, 3],
'type': 'bar', 'name': 'SF'},
{'x': [1, 2, 3], 'y': [5, 4, 3],
'type': 'bar', 'name': 'Montréal'},
]
}
)
]),
])
])
# if __name__ == '__main__':
# app.run(debug=True)
小技巧
请注意,这种方法有一个缺点:它要求您预先计算每个选项卡的 children
属性,并一次性通过网络发送所有选项卡的内容。回调方法允许您在需要时(即点击选项卡时)动态计算选项卡的内容。
样式化选项卡组件#
使用 CSS 类#
通过为 className
属性提供自定义的 CSS 类,可以使用 CSS 类来样式化 Tabs
(和 Tab
)组件:
from dash import Dash, dcc, html, Input, Output, callback
app = Dash(__name__)
app.layout = html.Div([
dcc.Tabs(
id="tabs-with-classes",
value='tab-2',
parent_className='custom-tabs',
className='custom-tabs-container',
children=[
dcc.Tab(
label='Tab one',
value='tab-1',
className='custom-tab',
selected_className='custom-tab--selected'
),
dcc.Tab(
label='Tab two',
value='tab-2',
className='custom-tab',
selected_className='custom-tab--selected'
),
dcc.Tab(
label='Tab three, multiline',
value='tab-3', className='custom-tab',
selected_className='custom-tab--selected'
),
dcc.Tab(
label='Tab four',
value='tab-4',
className='custom-tab',
selected_className='custom-tab--selected'
),
]),
html.Div(id='tabs-content-classes')
])
@callback(Output('tabs-content-classes', 'children'),
Input('tabs-with-classes', 'value'))
def render_content(tab):
if tab == 'tab-1':
return html.Div([
html.H3('Tab content 1')
])
elif tab == 'tab-2':
return html.Div([
html.H3('Tab content 2')
])
elif tab == 'tab-3':
return html.Div([
html.H3('Tab content 3')
])
elif tab == 'tab-4':
return html.Div([
html.H3('Tab content 4')
])
# if __name__ == '__main__':
# app.run(debug=True)
请注意,通过为 parent_className
属性提供一个类,我们也可以对 Tabs
的容器进行样式化,这里我们使用它来在下方绘制边框,将实际的 Tabs
(带内边距)更居中地定位。我们还为常规的 Tab
组件添加了 display: flex
和 justify-content: center
,以便多行标签不会破坏文本的流动。相应的 CSS 文件(assets/tabs.css
)如下所示。将该文件保存在 assets/
文件夹中(可以根据您的需要命名)。Dash 会在加载应用时自动包含此 CSS。
.custom-tabs-container {
width: 85%;
}
.custom-tabs {
border-top-left-radius: 3px;
background-color: #f9f9f9;
padding: 0px 24px;
border-bottom: 1px solid #d6d6d6;
}
.custom-tab {
color:#586069;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
border-top: 3px solid transparent !important;
border-left: 0px !important;
border-right: 0px !important;
border-bottom: 0px !important;
background-color: #fafbfc;
padding: 12px !important;
font-family: "system-ui";
display: flex !important;
align-items: center;
justify-content: center;
}
.custom-tab--selected {
color: black;
box-shadow: 1px 1px 0px white;
border-left: 1px solid lightgrey !important;
border-right: 1px solid lightgrey !important;
border-top: 3px solid #e36209 !important;
}
使用内联样式#
提供 CSS 类的一种替代方法是直接提供样式字典:
from dash import Dash, dcc, html, Input, Output, callback
app = Dash(__name__)
tabs_styles = {
'height': '44px'
}
tab_style = {
'borderBottom': '1px solid #d6d6d6',
'padding': '6px',
'fontWeight': 'bold'
}
tab_selected_style = {
'borderTop': '1px solid #d6d6d6',
'borderBottom': '1px solid #d6d6d6',
'backgroundColor': '#119DFF',
'color': 'white',
'padding': '6px'
}
app.layout = html.Div([
dcc.Tabs(id="tabs-styled-with-inline", value='tab-1', children=[
dcc.Tab(label='Tab 1', value='tab-1', style=tab_style, selected_style=tab_selected_style),
dcc.Tab(label='Tab 2', value='tab-2', style=tab_style, selected_style=tab_selected_style),
dcc.Tab(label='Tab 3', value='tab-3', style=tab_style, selected_style=tab_selected_style),
dcc.Tab(label='Tab 4', value='tab-4', style=tab_style, selected_style=tab_selected_style),
], style=tabs_styles),
html.Div(id='tabs-content-inline')
])
@callback(Output('tabs-content-inline', 'children'),
Input('tabs-styled-with-inline', 'value'))
def render_content(tab):
if tab == 'tab-1':
return html.Div([
html.H3('Tab content 1')
])
elif tab == 'tab-2':
return html.Div([
html.H3('Tab content 2')
])
elif tab == 'tab-3':
return html.Div([
html.H3('Tab content 3')
])
elif tab == 'tab-4':
return html.Div([
html.H3('Tab content 4')
])
# if __name__ == '__main__':
# app.run(debug=True)
最后,您可以通过在字典中指定 "border"
(边框)、"primary"
(主要)和 "background"
(背景)颜色来设置 Tabs
组件的颜色属性。如果您要使用它们,请确保都设置了!
from dash import Dash, dcc, html, Input, Output, callback
app = Dash(__name__)
app.layout = html.Div([
dcc.Tabs(id="tabs-styled-with-props", value='tab-1', children=[
dcc.Tab(label='1', value='tab-1'),
dcc.Tab(label='2', value='tab-2'),
], colors={
"border": "white",
"primary": "gold",
"background": "cornsilk"
}),
html.Div(id='tabs-content-props')
])
@callback(Output('tabs-content-props', 'children'),
Input('tabs-styled-with-props', 'value'))
def render_content(tab):
if tab == 'tab-1':
return html.Div([
html.H3('Tab content 1')
])
elif tab == 'tab-2':
return html.Div([
html.H3('Tab content 2')
])
# if __name__ == '__main__':
# app.run(debug=True)