小言_互联网的博客

Python+Dash快速web应用开发——页面布局篇

394人阅读  评论(0)


添加微信号"CNFeffery"加入技术交流群

本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes

1 简介

这是我的系列教程「Python+Dash快速web应用开发」的第二期,在上一期中,我带领大家认识了什么是DashDash可以做什么,以及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


   
  1. import dash
  2. import dash_bootstrap_components as dbc
  3. app = dash.Dash(
  4.     __name__,
  5.     # 从国内可顺畅访问的cdn获取所需的原生bootstrap对应css
  6.     external_stylesheets=[ 'https://cdn.staticfile.org/twitter-bootstrap/4.5.2/css/bootstrap.min.css']
  7. )
  8. app.layout = dbc.Alert(
  9.      "你好,dash_bootstrap_components!"
  10. )
  11. if __name__ ==  "__main__":
  12.     app.run_server()

执行后打开所提示的网址,看到下列信息就说明安装成功:

图3

这里我们使用到dash.Dash()中的参数external_stylesheets,用于引入外部的css文件,有了这些补充进来的css,我们才得以实现更多彩的样式,而除了上述填入url的方式之外,我更推荐的方式是在我们的Dash应用.py文件同级目录创建文件夹assets,放在这个目录中的文件会被Dash自动扫描到:

app2.py


   
  1. import dash
  2. import dash_bootstrap_components as dbc
  3. app = dash.Dash(
  4.     __name__,
  5.     # 直接填写assets下css文件路径+文件名
  6.     external_stylesheets=[ 'css/bootstrap.min.css']
  7. )
  8. app.layout = dbc.Alert(
  9.      "你好,dash_bootstrap_components!"
  10. )
  11. if __name__ ==  "__main__":
  12.     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


   
  1. import dash
  2. import dash_bootstrap_components as dbc
  3. import dash_core_components as dcc
  4. import dash_html_components as html
  5. app = dash.Dash(
  6.     __name__,
  7.     external_stylesheets=[ 'css/bootstrap.min.css']
  8. )
  9. app.layout = html.Div(
  10.     [
  11.         # fluid默认为False
  12.         dbc.Container(
  13.             [
  14.                 dcc.Dropdown(),
  15.                  '测试',
  16.                 dcc.Dropdown()
  17.             ]
  18.         ),
  19.         html.Hr(), # 水平分割线
  20.         # fluid设置为True
  21.         dbc.Container(
  22.             [
  23.                 dcc.Dropdown(),
  24.                  '测试',
  25.                 dcc.Dropdown()
  26.             ],
  27.             fluid=True
  28.         )
  29.     ]
  30. )
  31. if __name__ ==  "__main__":
  32.     app.run_server()
图6

可以看到,第一个Container()部分呈现出两边空白填充中间居中的形式,而第二个则充满了整个水平方向。

  • 「Row()与Col()」

在上面所介绍的Container()之内,我们就可以按照bootstrap的网格系统进行内容的排布:「行」嵌套「列」,再向「列」内嵌套各种部件。

而所谓的网格系统指的是每个Row()部件内部分成宽度相等的「12」份,传入的Col()部件具有参数width可以传入「整数」来分配对应数量的宽度,如下例:

app4.py


   
  1. import dash
  2. import dash_bootstrap_components as dbc
  3. app = dash.Dash(
  4.     __name__,
  5.     external_stylesheets=[ 'css/bootstrap.min.css']
  6. )
  7. app.layout = dbc.Container(
  8.     [
  9.         dbc.Row(dbc.Col( '第一行'),
  10.                 style={
  11.                      'background-color''lightgreen'
  12.                 }),
  13.         dbc.Row(
  14.             [
  15.                 dbc.Col( '第二行第一列', width= 6, style={ 'background-color''lightblue'}),
  16.                 dbc.Col( '第二行第二列', width= 6, style={ 'background-color''lightskyblue'})
  17.             ]
  18.         ),
  19.         dbc.Row(
  20.             [
  21.                 dbc.Col( '第三行第一列', width= 2, style={ 'background-color''HotPink'}),
  22.                 dbc.Col( '第三行第二列', width= 10, style={ 'background-color''IndianRed'})
  23.             ]
  24.         ),
  25.         dbc.Row(
  26.             [
  27.                 dbc.Col( '第四行第一列', width= 2, style={ 'background-color''HotPink'}),
  28.                 dbc.Col( '第四行第二列', width= 2, style={ 'background-color''IndianRed'}),
  29.                 dbc.Col( '第四行第三列', width= 2, style={ 'background-color''HotPink'})
  30.             ]
  31.         ),
  32.         dbc.Row(
  33.             [
  34.                 dbc.Col( '第五行第一列', width= 2, style={ 'background-color''LightSteelBlue'}),
  35.                 dbc.Col( '第五行第二列', width= 11, style={ 'background-color''MistyRose'}),
  36.             ]
  37.         )
  38.     ]
  39. )
  40. if __name__ ==  "__main__":
  41.     app.run_server()
图7

可以看到当Row()部件下所有Col()部件宽度之和为12时是正好充满的,当宽度之和不足12时剩余的宽度会被空出来,而宽度之和若大于12,则会把导致宽度溢出的Col()部件挤到下一行中,所以我们在利用这种网格系统排布网页元素时要注意规范。

「行部件」也是可以嵌套到上一级「列部件」中的,因此如果你觉得12份不够自己实现更精确的宽度分配,就可以写个嵌套,实现固定宽度下再次划分12份,就像下面例子中我们:

app5.py


   
  1. import dash
  2. import dash_bootstrap_components as dbc
  3. app = dash.Dash(
  4.     __name__,
  5.     external_stylesheets=[ 'css/bootstrap.min.css']
  6. )
  7. app.layout = dbc.Container(
  8.     [
  9.         dbc.Row(dbc.Col( '第一行'),
  10.                 style={
  11.                      'background-color''lightgreen'
  12.                 }),
  13.         dbc.Row(
  14.             [
  15.                 dbc.Col( '第二行第一列', width= 6, style={ 'background-color''lightblue'}),
  16.                 dbc.Col(
  17.                     dbc.Row(
  18.                         [
  19.                             dbc.Col( '嵌套1', width= 6, style={ 'background-color''Moccasin'}),
  20.                             dbc.Col( '嵌套2', width= 3, style={ 'background-color''lightskyblue'}),
  21.                             dbc.Col( '嵌套3', width= 3, style={ 'background-color''Moccasin'}),
  22.                         ]
  23.                     ),
  24.                     width= 6,
  25.                     style={ 'background-color''lightskyblue'})
  26.             ]
  27.         )
  28.     ]
  29. )
  30. if __name__ ==  "__main__":
  31.     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


   
  1. import dash
  2. import dash_bootstrap_components as dbc
  3. import dash_html_components as html
  4. app = dash.Dash(
  5.     __name__,
  6.     external_stylesheets=[ 'css/bootstrap.min.css']
  7. )
  8. app.layout = html.Div(
  9.     dbc.Container(
  10.         [
  11.             html.Br(),
  12.             html.Br(),
  13.             html.Br(),
  14.             dbc.Row(
  15.                 [
  16.                     dbc.Col( '1', width= 2, style={ 'background-color''lightblue'}),
  17.                     dbc.Col( '2', width= 2, style={ 'background-color''lightskyblue'}),
  18.                     dbc.Col( '3', width= 2, style={ 'background-color''#e88b00'}),
  19.                     dbc.Col( '4', width= 2, style={ 'background-color''#8c8c8c'})
  20.                 ]
  21.             ),
  22.             html.Br(),
  23.             dbc.Row(
  24.                 [
  25.                     dbc.Col( 'order=last', width={ 'size'2'order''last'}, style={ 'background-color''lightblue'}),
  26.                     dbc.Col( 'order=2', width={ 'size'2'order'2}, style={ 'background-color''lightskyblue'}),
  27.                     dbc.Col( 'order=1', width={ 'size'2'order'1}, style={ 'background-color''#e88b00'}),
  28.                     dbc.Col( 'order=first', width={ 'size'2'order''first'}, style={ 'background-color''#8c8c8c'})
  29.                 ]
  30.             )
  31.         ]
  32.     )
  33. )
  34. if __name__ ==  '__main__':
  35.     app.run_server()

可以很直观地看出order参数对列部件顺序的影响:

图10
  • 「利用offset设置偏移」

列部件的width参数字典中还可以使用键值对参数offset,传入1到12的整数,它的作用是为对应的Col()部件左侧增加对应宽度的位移,就像下面的例子一样:

app8.py


   
  1. import dash
  2. import dash_bootstrap_components as dbc
  3. import dash_html_components as html
  4. app = dash.Dash(
  5.     __name__,
  6.     external_stylesheets=[ 'css/bootstrap.min.css']
  7. )
  8. app.layout = html.Div(
  9.     dbc.Container(
  10.         [
  11.             html.Br(),
  12.             html.Br(),
  13.             html.Br(),
  14.             dbc.Row(
  15.                 [
  16.                     dbc.Col( '1', width= 2, style={ 'background-color''lightblue'}),
  17.                     dbc.Col( '2', width= 2, style={ 'background-color''lightskyblue'}),
  18.                     dbc.Col( '3', width= 2, style={ 'background-color''#e88b00'}),
  19.                     dbc.Col( '4', width= 2, style={ 'background-color''#8c8c8c'})
  20.                 ],
  21.                 style={ 'border''1px solid black'}
  22.             ),
  23.             html.Br(),
  24.             dbc.Row(
  25.                 [
  26.                     dbc.Col( 'offset=1', width={ 'size'2'offset'1}, style={ 'background-color''lightblue'}),
  27.                     dbc.Col( 'offset=2', width={ 'size'2'offset'2}, style={ 'background-color''lightskyblue'}),
  28.                     dbc.Col( '3', width= 2, style={ 'background-color''#e88b00'}),
  29.                     dbc.Col( 'offset=1', width={ 'size'2'offset'1}, style={ 'background-color''#8c8c8c'})
  30.                 ],
  31.                 style={ 'border''1px solid black'}
  32.             )
  33.         ]
  34.     )
  35. )
  36. if __name__ ==  '__main__':
  37.     app.run_server()

为了更明显,我给每个Row()部件加了轮廓线,可以看到效果非常直观:

图11
  • 「设置水平对齐方式」

在前面的内容中,我们在同一个Row()部件下组织的所有Col()部件,其顺序都是从左到右一个紧贴下一个排布的,即使设置了offset参数,也只是插空后紧贴。

但在很多页面布局需求中需要对于同一行的多个列元素设置「对齐方式」,这在dash-bootstrap-components中可以通过对Row()部件设置参数justify来实现,可选项有'start''center''end''between'以及'around'五种,每种产生的效果如下面的例子:

app9.py


   
  1. import dash
  2. import dash_bootstrap_components as dbc
  3. import dash_html_components as html
  4. app = dash.Dash(
  5.     __name__,
  6.     external_stylesheets=[ 'css/bootstrap.min.css']
  7. )
  8. app.layout = html.Div(
  9.     dbc.Container(
  10.         [
  11.             html.Br(),
  12.             html.Br(),
  13.             html.Br(),
  14.             dbc.Row(
  15.                 [
  16.                     dbc.Col( 'start', width= 3, style={ 'border''1px solid black'}),
  17.                     dbc.Col( 'start', width= 3, style={ 'border''1px solid black'}),
  18.                     dbc.Col( 'start', width= 3, style={ 'border''1px solid black'})
  19.                 ],
  20.                 justify= 'start'
  21.             ),
  22.             html.Br(),
  23.             dbc.Row(
  24.                 [
  25.                     dbc.Col( 'center', width= 3, style={ 'border''1px solid black'}),
  26.                     dbc.Col( 'center', width= 3, style={ 'border''1px solid black'}),
  27.                     dbc.Col( 'center', width= 3, style={ 'border''1px solid black'})
  28.                 ],
  29.                 justify= 'center'
  30.             ),
  31.             html.Br(),
  32.             dbc.Row(
  33.                 [
  34.                     dbc.Col( 'end', width= 3, style={ 'border''1px solid black'}),
  35.                     dbc.Col( 'end', width= 3, style={ 'border''1px solid black'}),
  36.                     dbc.Col( 'end', width= 3, style={ 'border''1px solid black'})
  37.                 ],
  38.                 justify= 'end'
  39.             ),
  40.             html.Br(),
  41.             dbc.Row(
  42.                 [
  43.                     dbc.Col( 'between', width= 3, style={ 'border''1px solid black'}),
  44.                     dbc.Col( 'between', width= 3, style={ 'border''1px solid black'}),
  45.                     dbc.Col( 'between', width= 3, style={ 'border''1px solid black'})
  46.                 ],
  47.                 justify= 'between'
  48.             ),
  49.             html.Br(),
  50.             dbc.Row(
  51.                 [
  52.                     dbc.Col( 'around', width= 3, style={ 'border''1px solid black'}),
  53.                     dbc.Col( 'around', width= 3, style={ 'border''1px solid black'}),
  54.                     dbc.Col( 'around', width= 3, style={ 'border''1px solid black'})
  55.                 ],
  56.                 justify= 'around'
  57.             )
  58.         ],
  59.         # 为Container两边添加参考线
  60.         style={ 'border-left''1px solid red''border-right''1px solid red'}
  61.     )
  62. )
  63. if __name__ ==  '__main__':
  64.     app.run_server()
图12

2.3 实际案例

通过对上面知识内容的学习,我们掌握了如何基于拓展库dash-bootstrap-components,在Dash中实现bootstrap的网格系统。

下面我们来利用今天学到的知识点,搭建下图所示的登录页面,其中涉及到一些还未给大家介绍的知识点,但很简单,之后的课程会介绍,而涉及到一些额外的css的内容我都已写好注释非常简单~

图13

对应代码如下:

app10.py


   
  1. import dash
  2. import dash_html_components as html
  3. import dash_bootstrap_components as dbc
  4. app = dash.Dash(
  5.     __name__,
  6.     external_stylesheets=[ 'css/bootstrap.min.css']
  7. )
  8. app.layout = html.Div(
  9.     [
  10.         html.Br(),
  11.         html.Br(),
  12.         html.Br(),
  13.         html.Br(),
  14.         html.Br(),
  15.         html.Br(),
  16.         html.Br(),
  17.         html.Br(),
  18.         dbc.Container(
  19.             [
  20.                 dbc.Row(style={ 'height''30px'}),  # 利用css设置高度
  21.                 dbc.Row(
  22.                     dbc.Col( 'Email address')
  23.                 ),
  24.                 dbc.Row(
  25.                     dbc.Col(dbc.Input(placeholder= 'Enter email'))
  26.                 ),
  27.                 dbc.Row(
  28.                     dbc.Col( 'Password')
  29.                 ),
  30.                 dbc.Row(
  31.                     dbc.Col(dbc.Input(placeholder= 'Enter Password'))
  32.                 ),
  33.                 dbc.Row(
  34.                     dbc.Col(
  35.                         [
  36.                              'By signing up you accept our ',
  37.                             html.A( 'Terms Of Use', href= '#')
  38.                         ],
  39.                         width={ 'size'10'offset'1},
  40.                         style={ 'text-align''center'}  # 利用css设置文字居中
  41.                     ),
  42.                     style={ 'margin''6px'}  # 利用css设置上下留白高度
  43.                 ),
  44.                 dbc.Row(
  45.                     dbc.Col(
  46.                         # 利用css实现圆角矩形效果
  47.                         dbc.Button( 'LOGIN', style={ 'border-radius''18px'}, block=True),
  48.                         width={ 'size'8'offset'2},
  49.                         style={ 'text-align''center'}
  50.                     )
  51.                 ),
  52.                 dbc.Row(
  53.                     [
  54.                         dbc.Col(html.Hr()),
  55.                         html.P( 'or', style={ 'text-align''center''margin'0}),
  56.                         dbc.Col(html.Hr())
  57.                     ]
  58.                 ),
  59.                 dbc.Row(
  60.                     dbc.Col(
  61.                         dbc.Button(
  62.                              'Signup using Google',
  63.                             style={ 'border-radius''18px'},
  64.                             block=True,
  65.                             outline=True
  66.                         ),
  67.                         width={ 'size'8'offset'2},
  68.                         style={ 'text-align''center'}
  69.                     )
  70.                 ),
  71.                 dbc.Row(
  72.                     dbc.Col(
  73.                         [
  74.                              "Don't have account? ",
  75.                             html.A( 'Sign up here', href= '#')
  76.                         ],
  77.                         width={ 'size'10'offset'1},
  78.                         style={ 'text-align''center'}
  79.                     ),
  80.                     style={ 'margin''6px'}
  81.                 ),
  82.                 html.Br(),
  83.             ],
  84.             style={
  85.                  'background-color''#ededef',  # 设置背景颜色
  86.                  'max-width''480px',  # 为Container部件设置最大宽度
  87.                  'border-radius''12px'
  88.             }
  89.         )
  90.     ]
  91. )
  92. if __name__ ==  '__main__':
  93.     app.run_server()

以上就是本文的全部内容,欢迎在评论区与我进行讨论,「点赞」越多下一期更新越快哦????~

加入我们的知识星球【我们谈论数据科学】

爱上数据分析!



· 推荐阅读 ·

Python+Dash快速web应用开发——基础概念篇

不吹不黑,jupyter lab 3.0客观使用体验

图解NumPy:常用函数的内在机制


转载:https://blog.csdn.net/baoqiangwang/article/details/112691036
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场