(數據科學學習手札103)Python+Dash快速web應用開發——頁面佈局篇

本文示例代碼已上傳至個人Github倉庫https://github.com/CNFeffery/DataScienceStudyNotescss

1 簡介

   這是個人系列教程Python+Dash快速web應用開發的第二期,在上一期中,我帶領你們認識了什麼是DashDash能夠作什麼,以及Dash中最基本的一些概念,而今天開始,我將開始帶領你們正式學習有關Dash的實用知識,以及各類奇淫巧技😋~html

圖1

  今天的文章,我將帶你們學習Dash頁面佈局的先進方法,經過今天的文章,你將學會以很是簡單的方式實現現代化的頁面佈局,下面讓咱們開始吧~前端

2 爲Dash應用設計頁面佈局

  咱們都知道,一個好的網頁設計一般都須要編寫css甚至js來定製前端內容,譬如很是流行的bootstrap框架。python

圖2

  但咱們既然想使用Dash來搭建web應用,很大的一個緣由是不熟悉或者不想寫繁瑣的前端代碼,而Dash的第三方拓展庫中就有這麼一個Python庫——dash-bootstrap-components,藉助它,咱們就能夠純Python編程調用到 bootstrap框架中的諸多特性來讓咱們的web應用頁面更美觀。git

  首先須要經過pip install dash-bootstrap-components來安裝它,安裝完成以後,咱們來驗證一下是否能夠正常使用,推薦以import dash_bootstrap_components as dbc的方式導入:github

app1.pyweb

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自動掃描到:bootstrap

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()

  以上就是本文的所有內容,歡迎在評論區與我進行討論,點贊越多下一期更新越快哦😋~

相關文章
相關標籤/搜索