添加微信号"CNFeffery"加入技术交流群
❝本文示例代码已上传至我的
❞Github
仓库https://github.com/CNFeffery/DataScienceStudyNotes
1 简介
这是我的系列教程「Python+Dash快速web应用开发」的第二期,在上一期中,我带领大家认识了什么是Dash
,Dash
可以做什么,以及Dash
中最基本的一些概念,而今天开始,我将开始带领大家正式学习有关Dash
的实用知识,以及各种奇淫巧技????~
今天的文章,我将带大家学习Dash
中「页面布局」的先进方法,通过今天的文章,你将学会以非常简单的方式实现现代化的页面布局,下面让我们开始吧~
2 为Dash应用设计页面布局
我们都知道,一个好的网页设计通常都需要编写css
甚至js
来定制前端内容,譬如非常流行的bootstrap
框架。
但我们既然想使用Dash
来搭建web应用,很大的一个原因是不熟悉或者不想写繁琐的前端代码,而Dash
的第三方拓展库中就有这么一个Python
库——dash-bootstrap-components
,借助它,我们就可以纯Python
编程调用到 bootstrap
框架中的诸多特性来让我们的web应用页面更美观。
首先需要通过pip install dash-bootstrap-components
来安装它,安装完成之后,我们来验证一下是否可以正常使用,推荐以import dash_bootstrap_components as dbc
的方式导入:
❝app1.py
❞
-
import dash
-
import dash_bootstrap_components as dbc
-
-
app = dash.Dash(
-
__name__,
-
# 从国内可顺畅访问的cdn获取所需的原生bootstrap对应css
-
external_stylesheets=[
'https://cdn.staticfile.org/twitter-bootstrap/4.5.2/css/bootstrap.min.css']
-
)
-
-
app.layout = dbc.Alert(
-
"你好,dash_bootstrap_components!"
-
)
-
-
if __name__ ==
"__main__":
-
app.run_server()
执行后打开所提示的网址,看到下列信息就说明安装成功:
图3这里我们使用到dash.Dash()
中的参数external_stylesheets
,用于引入外部的css
文件,有了这些补充进来的css
,我们才得以实现更多彩的样式,而除了上述填入url
的方式之外,我更推荐的方式是在我们的Dash
应用.py
文件同级目录创建文件夹assets
,放在这个目录中的文件会被Dash
自动扫描到:
❝app2.py
❞
-
import dash
-
import dash_bootstrap_components as dbc
-
-
app = dash.Dash(
-
__name__,
-
# 直接填写assets下css文件路径+文件名
-
external_stylesheets=[
'css/bootstrap.min.css']
-
)
-
-
app.layout = dbc.Alert(
-
"你好,dash_bootstrap_components!"
-
)
-
-
if __name__ ==
"__main__":
-
app.run_server()
图4
这时在Dash
页面抓包可以看到对应bootstrap.min.css
的url信息指向域名下的对应目录:
这种方式最稳妥,不受网络波动影响,推荐大家养成好习惯。
在测试完dash-bootstrap-components
的可用性之后,接下来我们就开始学习构造页面布局。
2.1 认识Container()、Row()与Col()
「Container()」
dash-bootstrap-components
封装了bootstrap
框架中的「网格系统」,我们在使用它进行布局时,首先要了解的是组件Container()
,它是我们组织页面元素的容器,其参数fluid
默认为False,会以两边填充空白区域的方式居中其内部嵌套的子元素:
❝app3.py
❞
-
import dash
-
import dash_bootstrap_components as dbc
-
import dash_core_components as dcc
-
import dash_html_components as html
-
-
app = dash.Dash(
-
__name__,
-
external_stylesheets=[
'css/bootstrap.min.css']
-
)
-
-
app.layout = html.Div(
-
[
-
# fluid默认为False
-
dbc.Container(
-
[
-
dcc.Dropdown(),
-
'测试',
-
dcc.Dropdown()
-
]
-
),
-
-
html.Hr(), # 水平分割线
-
-
# fluid设置为True
-
dbc.Container(
-
[
-
dcc.Dropdown(),
-
'测试',
-
dcc.Dropdown()
-
],
-
fluid=True
-
)
-
]
-
)
-
-
if __name__ ==
"__main__":
-
app.run_server()
图6
可以看到,第一个Container()
部分呈现出两边空白填充中间居中的形式,而第二个则充满了整个水平方向。
「Row()与Col()」
在上面所介绍的Container()
之内,我们就可以按照bootstrap
的网格系统进行内容的排布:「行」嵌套「列」,再向「列」内嵌套各种部件。
而所谓的网格系统指的是每个Row()
部件内部分成宽度相等的「12」份,传入的Col()
部件具有参数width
可以传入「整数」来分配对应数量的宽度,如下例:
❝app4.py
❞
-
import dash
-
import dash_bootstrap_components as dbc
-
-
app = dash.Dash(
-
__name__,
-
external_stylesheets=[
'css/bootstrap.min.css']
-
)
-
-
app.layout = dbc.Container(
-
[
-
dbc.Row(dbc.Col(
'第一行'),
-
style={
-
'background-color':
'lightgreen'
-
}),
-
dbc.Row(
-
[
-
dbc.Col(
'第二行第一列', width=
6, style={
'background-color':
'lightblue'}),
-
dbc.Col(
'第二行第二列', width=
6, style={
'background-color':
'lightskyblue'})
-
]
-
),
-
dbc.Row(
-
[
-
dbc.Col(
'第三行第一列', width=
2, style={
'background-color':
'HotPink'}),
-
dbc.Col(
'第三行第二列', width=
10, style={
'background-color':
'IndianRed'})
-
]
-
),
-
dbc.Row(
-
[
-
dbc.Col(
'第四行第一列', width=
2, style={
'background-color':
'HotPink'}),
-
dbc.Col(
'第四行第二列', width=
2, style={
'background-color':
'IndianRed'}),
-
dbc.Col(
'第四行第三列', width=
2, style={
'background-color':
'HotPink'})
-
]
-
),
-
dbc.Row(
-
[
-
dbc.Col(
'第五行第一列', width=
2, style={
'background-color':
'LightSteelBlue'}),
-
dbc.Col(
'第五行第二列', width=
11, style={
'background-color':
'MistyRose'}),
-
]
-
)
-
]
-
)
-
-
if __name__ ==
"__main__":
-
app.run_server()
图7
可以看到当Row()
部件下所有Col()
部件宽度之和为12时是正好充满的,当宽度之和不足12时剩余的宽度会被空出来,而宽度之和若大于12,则会把导致宽度溢出的Col()
部件挤到下一行中,所以我们在利用这种网格系统排布网页元素时要注意规范。
而「行部件」也是可以嵌套到上一级「列部件」中的,因此如果你觉得12份不够自己实现更精确的宽度分配,就可以写个嵌套,实现固定宽度下再次划分12份,就像下面例子中我们:
❝app5.py
❞
-
import dash
-
import dash_bootstrap_components as dbc
-
-
app = dash.Dash(
-
__name__,
-
external_stylesheets=[
'css/bootstrap.min.css']
-
)
-
-
app.layout = dbc.Container(
-
[
-
dbc.Row(dbc.Col(
'第一行'),
-
style={
-
'background-color':
'lightgreen'
-
}),
-
dbc.Row(
-
[
-
dbc.Col(
'第二行第一列', width=
6, style={
'background-color':
'lightblue'}),
-
dbc.Col(
-
dbc.Row(
-
[
-
dbc.Col(
'嵌套1', width=
6, style={
'background-color':
'Moccasin'}),
-
dbc.Col(
'嵌套2', width=
3, style={
'background-color':
'lightskyblue'}),
-
dbc.Col(
'嵌套3', width=
3, style={
'background-color':
'Moccasin'}),
-
]
-
),
-
width=
6,
-
style={
'background-color':
'lightskyblue'})
-
]
-
)
-
]
-
)
-
-
if __name__ ==
"__main__":
-
app.run_server()
图8
在get到这一小节的知识点后,我们就可以更规矩地编写页面内容,譬如写出下面这样的调查问卷就比较轻松(受限于篇幅,下面例子对应的app6.py
不便放出代码,你可以在文章开头的Github
仓库对应路径找到它):
❝图9app6.py
❞
2.2 Row()与Col()部件的进阶设置
通过上一小节的例子,想必你已经学习到如何在Dash
中编排出bootstrap
网格系统风格的页面,而为了在已初步编排好的网页基础上做更多实用优化,dash-bootstrap-components
还为Row()
与Col()
部件提供了一些微调布局的参数:
「利用order设定顺序」
我们在前面为Col()
部件所设定的width
参数都只是1到12之间的整数,其实它还可以接受字典输入,从而拓展其功能,原先的整数宽度输入就由width=n
转化为width={'size': n}
。
除此之外,我们还可以添加order
键参数来为同一个Row()
下的部件设置顺序,接受三种输入:'first'
表示置于当前行第一列,'last'
表示置于当前行最后一列,而1到12的整数则可以直接以序号编排列部件顺序。
结合下面这个简单的例子理解这部分内容:
❝app7.py
❞
-
import dash
-
import dash_bootstrap_components as dbc
-
import dash_html_components as html
-
-
app = dash.Dash(
-
__name__,
-
external_stylesheets=[
'css/bootstrap.min.css']
-
)
-
-
app.layout = html.Div(
-
dbc.Container(
-
[
-
html.Br(),
-
html.Br(),
-
html.Br(),
-
dbc.Row(
-
[
-
dbc.Col(
'1', width=
2, style={
'background-color':
'lightblue'}),
-
dbc.Col(
'2', width=
2, style={
'background-color':
'lightskyblue'}),
-
dbc.Col(
'3', width=
2, style={
'background-color':
'#e88b00'}),
-
dbc.Col(
'4', width=
2, style={
'background-color':
'#8c8c8c'})
-
]
-
),
-
html.Br(),
-
dbc.Row(
-
[
-
dbc.Col(
'order=last', width={
'size':
2,
'order':
'last'}, style={
'background-color':
'lightblue'}),
-
dbc.Col(
'order=2', width={
'size':
2,
'order':
2}, style={
'background-color':
'lightskyblue'}),
-
dbc.Col(
'order=1', width={
'size':
2,
'order':
1}, style={
'background-color':
'#e88b00'}),
-
dbc.Col(
'order=first', width={
'size':
2,
'order':
'first'}, style={
'background-color':
'#8c8c8c'})
-
]
-
)
-
]
-
)
-
)
-
-
if __name__ ==
'__main__':
-
app.run_server()
可以很直观地看出order
参数对列部件顺序的影响:
「利用offset设置偏移」
列部件的width
参数字典中还可以使用键值对参数offset
,传入1到12的整数,它的作用是为对应的Col()
部件左侧增加对应宽度的位移,就像下面的例子一样:
❝app8.py
❞
-
import dash
-
import dash_bootstrap_components as dbc
-
import dash_html_components as html
-
-
app = dash.Dash(
-
__name__,
-
external_stylesheets=[
'css/bootstrap.min.css']
-
)
-
-
app.layout = html.Div(
-
dbc.Container(
-
[
-
html.Br(),
-
html.Br(),
-
html.Br(),
-
dbc.Row(
-
[
-
dbc.Col(
'1', width=
2, style={
'background-color':
'lightblue'}),
-
dbc.Col(
'2', width=
2, style={
'background-color':
'lightskyblue'}),
-
dbc.Col(
'3', width=
2, style={
'background-color':
'#e88b00'}),
-
dbc.Col(
'4', width=
2, style={
'background-color':
'#8c8c8c'})
-
],
-
style={
'border':
'1px solid black'}
-
),
-
html.Br(),
-
dbc.Row(
-
[
-
dbc.Col(
'offset=1', width={
'size':
2,
'offset':
1}, style={
'background-color':
'lightblue'}),
-
dbc.Col(
'offset=2', width={
'size':
2,
'offset':
2}, style={
'background-color':
'lightskyblue'}),
-
dbc.Col(
'3', width=
2, style={
'background-color':
'#e88b00'}),
-
dbc.Col(
'offset=1', width={
'size':
2,
'offset':
1}, style={
'background-color':
'#8c8c8c'})
-
],
-
style={
'border':
'1px solid black'}
-
)
-
]
-
)
-
)
-
-
if __name__ ==
'__main__':
-
app.run_server()
为了更明显,我给每个Row()
部件加了轮廓线,可以看到效果非常直观:
「设置水平对齐方式」
在前面的内容中,我们在同一个Row()
部件下组织的所有Col()
部件,其顺序都是从左到右一个紧贴下一个排布的,即使设置了offset
参数,也只是插空后紧贴。
但在很多页面布局需求中需要对于同一行的多个列元素设置「对齐方式」,这在dash-bootstrap-components
中可以通过对Row()
部件设置参数justify
来实现,可选项有'start'
、'center'
、'end'
、'between'
以及'around'
五种,每种产生的效果如下面的例子:
❝app9.py
❞
-
import dash
-
import dash_bootstrap_components as dbc
-
import dash_html_components as html
-
-
app = dash.Dash(
-
__name__,
-
external_stylesheets=[
'css/bootstrap.min.css']
-
)
-
-
app.layout = html.Div(
-
dbc.Container(
-
[
-
html.Br(),
-
html.Br(),
-
html.Br(),
-
dbc.Row(
-
[
-
dbc.Col(
'start', width=
3, style={
'border':
'1px solid black'}),
-
dbc.Col(
'start', width=
3, style={
'border':
'1px solid black'}),
-
dbc.Col(
'start', width=
3, style={
'border':
'1px solid black'})
-
],
-
justify=
'start'
-
),
-
html.Br(),
-
dbc.Row(
-
[
-
dbc.Col(
'center', width=
3, style={
'border':
'1px solid black'}),
-
dbc.Col(
'center', width=
3, style={
'border':
'1px solid black'}),
-
dbc.Col(
'center', width=
3, style={
'border':
'1px solid black'})
-
],
-
justify=
'center'
-
),
-
html.Br(),
-
dbc.Row(
-
[
-
dbc.Col(
'end', width=
3, style={
'border':
'1px solid black'}),
-
dbc.Col(
'end', width=
3, style={
'border':
'1px solid black'}),
-
dbc.Col(
'end', width=
3, style={
'border':
'1px solid black'})
-
],
-
justify=
'end'
-
),
-
html.Br(),
-
dbc.Row(
-
[
-
dbc.Col(
'between', width=
3, style={
'border':
'1px solid black'}),
-
dbc.Col(
'between', width=
3, style={
'border':
'1px solid black'}),
-
dbc.Col(
'between', width=
3, style={
'border':
'1px solid black'})
-
],
-
justify=
'between'
-
),
-
html.Br(),
-
dbc.Row(
-
[
-
dbc.Col(
'around', width=
3, style={
'border':
'1px solid black'}),
-
dbc.Col(
'around', width=
3, style={
'border':
'1px solid black'}),
-
dbc.Col(
'around', width=
3, style={
'border':
'1px solid black'})
-
],
-
justify=
'around'
-
)
-
],
-
# 为Container两边添加参考线
-
style={
'border-left':
'1px solid red',
'border-right':
'1px solid red'}
-
)
-
)
-
-
if __name__ ==
'__main__':
-
app.run_server()
图12
2.3 实际案例
通过对上面知识内容的学习,我们掌握了如何基于拓展库dash-bootstrap-components
,在Dash
中实现bootstrap
的网格系统。
下面我们来利用今天学到的知识点,搭建下图所示的登录页面,其中涉及到一些还未给大家介绍的知识点,但很简单,之后的课程会介绍,而涉及到一些额外的css的内容我都已写好注释非常简单~
图13对应代码如下:
❝app10.py
❞
-
import dash
-
import dash_html_components as html
-
import dash_bootstrap_components as dbc
-
-
app = dash.Dash(
-
__name__,
-
external_stylesheets=[
'css/bootstrap.min.css']
-
)
-
-
app.layout = html.Div(
-
[
-
html.Br(),
-
html.Br(),
-
html.Br(),
-
html.Br(),
-
html.Br(),
-
html.Br(),
-
html.Br(),
-
html.Br(),
-
dbc.Container(
-
[
-
dbc.Row(style={
'height':
'30px'}), # 利用css设置高度
-
dbc.Row(
-
dbc.Col(
'Email address')
-
),
-
dbc.Row(
-
dbc.Col(dbc.Input(placeholder=
'Enter email'))
-
),
-
dbc.Row(
-
dbc.Col(
'Password')
-
),
-
dbc.Row(
-
dbc.Col(dbc.Input(placeholder=
'Enter Password'))
-
),
-
dbc.Row(
-
dbc.Col(
-
[
-
'By signing up you accept our ',
-
html.A(
'Terms Of Use', href=
'#')
-
],
-
width={
'size':
10,
'offset':
1},
-
style={
'text-align':
'center'} # 利用css设置文字居中
-
),
-
style={
'margin':
'6px'} # 利用css设置上下留白高度
-
),
-
dbc.Row(
-
dbc.Col(
-
# 利用css实现圆角矩形效果
-
dbc.Button(
'LOGIN', style={
'border-radius':
'18px'}, block=True),
-
width={
'size':
8,
'offset':
2},
-
style={
'text-align':
'center'}
-
)
-
),
-
dbc.Row(
-
[
-
dbc.Col(html.Hr()),
-
html.P(
'or', style={
'text-align':
'center',
'margin':
0}),
-
dbc.Col(html.Hr())
-
]
-
),
-
dbc.Row(
-
dbc.Col(
-
dbc.Button(
-
'Signup using Google',
-
style={
'border-radius':
'18px'},
-
block=True,
-
outline=True
-
),
-
width={
'size':
8,
'offset':
2},
-
style={
'text-align':
'center'}
-
)
-
),
-
dbc.Row(
-
dbc.Col(
-
[
-
"Don't have account? ",
-
html.A(
'Sign up here', href=
'#')
-
],
-
width={
'size':
10,
'offset':
1},
-
style={
'text-align':
'center'}
-
),
-
style={
'margin':
'6px'}
-
),
-
html.Br(),
-
],
-
style={
-
'background-color':
'#ededef', # 设置背景颜色
-
'max-width':
'480px', # 为Container部件设置最大宽度
-
'border-radius':
'12px'
-
}
-
)
-
]
-
)
-
-
if __name__ ==
'__main__':
-
app.run_server()
以上就是本文的全部内容,欢迎在评论区与我进行讨论,「点赞」越多下一期更新越快哦????~
加入我们的知识星球【我们谈论数据科学】
爱上数据分析!
· 推荐阅读 ·
转载:https://blog.csdn.net/baoqiangwang/article/details/112691036