(数据科学学习手札103)Python+Dash快速web应用开发——页面布局篇
本文示例代码已上传至我的
Github仓库https://github.com/CNFeffery/DataScienceStudyNotes
1 简介
这是我的系列教程Python+Dash快速web应用开发的第二期,在上一期中,我带领大家认识了什么是Dash,Dash可以做什么,以及Dash中最基本的一些概念,而今天开始,我将开始带领大家正式学习有关Dash的实用知识,以及各种奇淫巧技~
图1
今天的文章,我将带大家学习Dash中页面布局的先进方法,通过今天的文章,你将学会以非常简单的方式实现现代化的页面布局,下面让我们开始吧~
2 为Dash应用设计页面布局
我们都知道,一个好的网页设计通常都需要编写css甚至js来定制前端内容,譬如非常流行的bootstrap框架。
图2
但我们既然想使用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信息指向域名下的对应目录:
图5
这种方式最稳妥,不受网络波动影响,推荐大家养成好习惯。
在测试完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仓库对应路径找到它):
app6.py
图9
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参数对列部件顺序的影响:
图10
- 利用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()部件加了轮廓线,可以看到效果非常直观:
图11
- 设置水平对齐方式
在前面的内容中,我们在同一个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()
以上就是本文的全部内容,欢迎在评论区与我进行讨论,点赞越多下一期更新越快哦~
(数据科学学习手札103)Python+Dash快速web应用开发——页面布局篇的更多相关文章
- (数据科学学习手札102)Python+Dash快速web应用开发——基础概念篇
本文示例代码与数据已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的新系列教程Python+Dash快 ...
- (数据科学学习手札108)Python+Dash快速web应用开发——静态部件篇(上)
本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的系列教程Python+Dash快速web ...
- (数据科学学习手札109)Python+Dash快速web应用开发——静态部件篇(中)
本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的系列教程Python+Dash快速web ...
- (数据科学学习手札115)Python+Dash快速web应用开发——交互表格篇(上)
本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的系列教程Python+Dash快速web ...
- (数据科学学习手札116)Python+Dash快速web应用开发——交互表格篇(中)
本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的系列教程Python+Dash快速web ...
- (数据科学学习手札117)Python+Dash快速web应用开发——交互表格篇(下)
本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的系列教程Python+Dash快速web ...
- (数据科学学习手札118)Python+Dash快速web应用开发——特殊部件篇
本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的系列教程Python+Dash快速web ...
- (数据科学学习手札105)Python+Dash快速web应用开发——回调交互篇(中)
本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的系列教程Python+Dash快速web ...
- (数据科学学习手札106)Python+Dash快速web应用开发——回调交互篇(下)
本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的系列教程Python+Dash快速web ...
随机推荐
- 【题解】「AT4266」[ABC113B] Palace
AT4266 [ABC113B] Palace 水题解*n translation 有 \(n\) 个地方,第 \(i\) 个地方的海拔为 \(H_i\),该地方的温度为 \(T-H_i \times ...
- uniapp-vuex实现tabbar提示点
底部入口栏的红点提示是app中常见的功能,或者说是必要功能,通常用来提醒用户去查看或操作某个模块内容. 看项目性质如果需要比较多并且灵活的提示,则需要用到长连接技术. 1.红点提示是根据接口返回的数据 ...
- Int,String,Integer,double之间的类型的相互转换
Int整数,String字符串之间的类型的转换 int转成String 结果为: String转成int类型 结果为: double转成String 结果为: String转成double 结果为: ...
- Jmeter(4)断言
Jmeter添加断言,检查测试中得到的响应数据是否符合预期.以下介绍下响应断言,JSON断言 一.响应断言 1.创建测试计划: 添加线程组->添加取样器->添加察看结果树,运行后可查看接口 ...
- html2canvas使用心得
近两年做了几次微信H5活动的开发,为了达到传播分享的效果,通常最终都需要生成个性化的图片,供用户长按保存分享,在这里就把自己的一些使用心得记录下来,供其他小伙伴借鉴. 这里备注一下,我目前用的是 h ...
- Python高级语法-深浅拷贝-总结(4.2.1)
@ 目录 1.说明 2.代码 关于作者 1.说明 任何可变数据类型都牵扯到深浅拷贝 但是元组,常数等,不可变数据类型,无论浅拷贝,深拷贝都是指向 不管如何嵌套,一旦牵扯到可变数据类型,都会有深浅区别 ...
- Bootstrap留言板界面练习
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- 你真的理解了java单例模式吗?讲别人都忽略的细节!
前言:老刘这篇文章敢做保证,java的单例模式讲的比大多数的技术博客都要好,讲述别人技术博客都没有的细节!!! 1 java单例模式 直接讲实现单例模式的两种方法:懒汉式和饿汉式,单例模式的概念自己上 ...
- 论文阅读: A Review of Robot Learning for Manipulation: Challenges, Representations, and Algorithms
机器人学习操纵综述:挑战,表示形式和算法 1.介绍 因此,研究人员专注于机器人应如何学习操纵周围世界的问题. 这项研究的范围很广,从学习个人操作技巧到人类演示,再到学习适用于高级计划的操作任务的抽象描 ...
- java中定时器设置时间
<!-- 0 0 10,14,16 * * ? 每天上午10点,下午2点,4点 0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时 0 0 12 ? * WED 表示每个星期三中午1 ...