本文示例程式碼已上傳至我的
Github
倉庫https://github.com/CNFeffery/DataScienceStudyNotes
1 簡介
這是我的系列教程Python+Dash快速web應用開發的第六期,在上一期的文章中,我們完成了對Dash
中回撥互動高階特性的探討,在今後陸續推出的教程內容中,我們將一起來學習Dash
生態中那些豐富的頁面部件,從而賦予我們打造各種強大互動式web應用的能力。
而在今天的教程內容中,我將帶大家學習Dash
中實用的一些基礎性的靜態部件,它們可以幫助我們打造更加正式的web應用。
2 Dash中的基礎靜態部件
我們在這裡所說的靜態頁面部件,主要指的是其本身不具備直接的互動功能,而是以呈現內容為主要功能,就像下面的簡單對比一樣:
app1.py
import dash
import dash_html_components as html
import dash_bootstrap_components as dbc
import dash_core_components as dcc
app = dash.Dash(__name__)
app.layout = html.Div(
dbc.Container(
[
html.Br(),
html.H1('靜態部件示例'),
html.Hr(),
html.H2('這是二級標題'),
html.H3('這是三級標題'),
html.H4('這是四級標題'),
html.P(
[
'這是一個',
html.A('連結', href='#'),
',而這是一段',
html.Strong('加粗文字'),
',這是一段帶上下標的文字:',
'測試',
html.Sup('上標'),
',測試',
html.Sub('下標')
]
),
html.Br(),
html.H1('互動部件示例'),
html.Br(),
dcc.Dropdown(
options=[
{'label': '測試1', 'value': '測試1'},
{'label': '測試2', 'value': '測試2'},
{'label': '測試3', 'value': '測試3'},
]),
html.Br(),
dcc.Checklist(
options=[
{'label': '測試1', 'value': '測試1'},
{'label': '測試2', 'value': '測試2'},
{'label': '測試3', 'value': '測試3'},
],
value=['測試1']
),
html.Br(),
dcc.RangeSlider(
min=0,
max=20,
step=0.5,
value=[5, 15]
)
]
)
)
if __name__ == '__main__':
app.run_server(debug=True)
可以看到,靜態部件其實就是我們平時瀏覽網頁看到的各種內容元素,他們本身不直接承擔回撥互動功能,只能配合其他互動部件來實現互動功能。
2.1 Dash中常用的基礎靜態部件
在Dash
中所整合的一些常用基礎性靜態部件,其實就是對一些常見html
元素的遷移,對應著dash_html_components
中封裝的眾多類,這裡我們只介紹部分比較常用的:
2.1.1 與文字格式相關的常用部件
首先我們來介紹Dash
眾多基礎靜態部件中,與組織頁面或文字格式相關的一些:
- H1()到H6()
在dash_html_components
中,H1()
到H6()
分別對應著1級到6級標題。
- Br()與Hr()
dash_html_components
中的Br()
表示換行,而Hr()
則表示水平分割線,這在我們佈局元素時經常使用到。
- P()
P()
用於表示一段文字或內容,典型如我們在部落格中看到的每一段落內容都是由P()
標籤所組織的,配合css
中的text-indent
屬性可以用來設定首行縮排。
- A()
A()
用於表示一個可點選的連結,其引數href
用於填入對應跳轉的地址,也可以配合id
,實現點選重新定位到頁面內的其它元素,其target
引數用於設定跳轉方式,譬如target="_blank"
會在新標籤頁跳轉開啟,具體內容可參考(https://www.w3school.com.cn/tags/att_a_target.asp)。
- I()、Code()、U()、Mark()
I()
主要用於在段落中將包裹的文字內容變為斜體,Code()
用於在一段文字中表示程式碼片段
,U()
用於給所包含內容新增下劃線,Mark()
則用於高亮標註文字。
以上所介紹的這些靜態部件可以通過下面的小例子直觀的感受一下:
app2.py
import dash
import dash_html_components as html
import dash_bootstrap_components as dbc
app = dash.Dash(__name__)
app.layout = html.Div(
dbc.Container(
[
html.H1('一級標題', id='demo1'),
html.H2('二級標題'),
html.H3('三級標題'),
html.H4('四級標題'),
html.H5('五級標題'),
html.H6('六級標題'),
html.Br(), # 換行
html.Hr(), # 水平分割線
html.P('這是一段文字。'*20),
html.P('這是另一段帶有首行縮排的文字。'*10, style={'text-indent': '3rem'}),
html.A('跳轉到費弗裡的Github倉庫',
target='_blank',
href='https://github.com/CNFeffery/DataScienceStudyNotes'), # 跳轉到外部連結
html.Br(),
html.A('跳轉到六級標題', href='#demo2'),
html.P(
[
'一段文字中出現了',
html.I('斜體'),
',以及程式碼片段',
html.Code('import dash'),
',還有一段',
html.U('帶下劃線的文字'),
',一段',
html.Mark('高亮標註文字'),
',以及另一段',
html.Mark('不同顏色的高亮標註文字。', style={'background-color': 'lightblue'})
]
)
] + [html.Br()] * 50 + [html.A('回到頂端一級標題', href='#demo1'),
html.H1('頁內元素跳轉示例標題', id='demo2')]
)
)
if __name__ == '__main__':
app.run_server(debug=True)
2.1.2 與內容組織相關的常用部件
前面我們針對常用的一些與文字格式相關的靜態部件進行了介紹,而在實際應用中我們不僅要展示文字內容,還需要展示圖片、音訊、視訊等多媒體內容,下面我們來學習如何在Dash
中構造更加豐富的內容展示形式:
- 基於Blockquote()實現塊引用
利用dash_html_components
中的Blockquote()
,我們可以直接傳入字串,或巢狀其他元素,從而構造出塊引用,就像markdown
中的>
所包含渲染的內容那樣,參考下面的例子:
app3.py
import dash
import dash_html_components as html
import dash_bootstrap_components as dbc
app = dash.Dash(__name__)
app.layout = html.Div(
dbc.Container(
html.Blockquote(
html.P('這是一段由塊引用包裹的文字內容' * 10),
style={
'background-color': 'rgba(211, 211, 211, 0.25)',
'text-indent': '3rem'
}
)
)
)
if __name__ == "__main__":
app.run_server(debug=True)
- 基於Ol()與Li()渲染有序列表
利用Ol()
巢狀多個Li()
,可以自動渲染出帶序號的有序列表,就像下面這個簡單的例子:
app4.py
import dash
import dash_html_components as html
import dash_bootstrap_components as dbc
app = dash.Dash(__name__)
app.layout = html.Div(
dbc.Container(
html.Ol(
[
html.Br(),
html.Br(),
html.Li('待辦事項1'),
html.Li('待辦事項2'),
html.Li('待辦事項3'),
html.Li('待辦事項4')
]
)
)
)
if __name__ == "__main__":
app.run_server(debug=True)
- 基於Ul()與Li()渲染層級列表
而除了與Ol()
相互配合之外,Li()
還可以巢狀在Ul()
中渲染帶層級關係的列表:
app5.py
import dash
import dash_html_components as html
import dash_bootstrap_components as dbc
app = dash.Dash(__name__)
app.layout = html.Div(
dbc.Container(
html.Ul(
[
html.Br(),
html.Br(),
html.Li('1'),
html.Li('2'),
html.Ul(
[
html.Li('2.1'),
html.Li('2.2'),
html.Li('2.3'),
html.Ul(
[
html.Li('2.1.1'),
html.Li('2.1.2'),
html.Li('2.1.3'),
]
)
]
),
html.Li('3'),
html.Li('4')
]
)
)
)
if __name__ == "__main__":
app.run_server(debug=True)
- 利用Img()渲染圖片
Img()
等價於html
中的img
標籤,我們通過src
引數傳入圖片地址來渲染出圖片,以我以前一篇部落格的作品圖片為例:
app6.py
import dash
import dash_html_components as html
import dash_bootstrap_components as dbc
app = dash.Dash(__name__)
app.layout = html.Div(
dbc.Container(
[
html.H5('(在模仿中精進資料視覺化05)疫情期間市值增長top25公司'),
html.Img(src='https://img2020.cnblogs.com/blog/1344061/202011/1344061-20201129183046286-1089258422.png',
style={'width': '100%'})
]
)
)
if __name__ == "__main__":
app.run_server(debug=True)
- 利用Audio()與Video()播放音訊與視訊
利用Audio()
和Video()
,我們可以通過引數src
傳入對應音訊與視訊檔案的url地址,從而實現在網頁中嵌入音訊與視訊,其中引數controls
必須設定為True
否則不會正常渲染:
app7.py
import dash
import dash_html_components as html
import dash_bootstrap_components as dbc
app = dash.Dash(__name__)
app.layout = html.Div(
dbc.Container(
[
html.H5('音訊示例:'),
html.Audio(src='https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3',
controls=True),
html.H5('視訊示例:'),
html.Video(src='https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4',
controls=True,
style={'width': '100%'}),
]
)
)
if __name__ == "__main__":
app.run_server(debug=True)
- 利用Iframe()嵌入其他網頁
類似iframe
標籤,我們也可以利用Iframe()
來在網頁中嵌入其他網頁,可以通過src
引數直接傳入目標網頁url,也可以通過srcDoc
引數傳入整個網頁的html原始碼字串:
app8.py
import dash
import dash_html_components as html
import dash_bootstrap_components as dbc
app = dash.Dash(__name__)
app.layout = html.Div(
dbc.Container(
[
html.Iframe(src='https://www.baidu.com/',
style={'width': '100%', 'height': '800px'})
]
)
)
if __name__ == "__main__":
app.run_server(debug=True)
- 利用Textarea()構造輸入框
有時候我們需要構造出一個能供使用者輸入大段文字的輸入框,譬如很多的線上編輯器,而在Dash
中我們可以使用dash_core_components
中的Textarea()
來實現這個功能,並且dcc.Textarea()
同樣具有value
和placeholder
屬性,可以配合回撥函式實現很多功能。
譬如下面的例子中我們編寫了一個簡單的髒話和諧工具,會將使用者輸入的所有他媽替換為“**”?:
app9.py
import dash
import dash_html_components as html
import dash_bootstrap_components as dbc
import dash_core_components as dcc
from dash.dependencies import Input, Output
app = dash.Dash(__name__)
app.layout = html.Div(
dbc.Container(
[
html.Br(),
dcc.Textarea(style={'width': '100%', 'height': '300px'},
id='input',
value='',
placeholder='請輸入文字內容!'),
html.P(id='output')
]
)
)
@app.callback(
Output('output', 'children'),
Input('input', 'value')
)
def mask_dirty_talk(value):
return value.replace('他媽', '**')
if __name__ == "__main__":
app.run_server(debug=True)
2.2 dcc.Markdown()——Dash中特殊的靜態部件
在Dash
中還存在一個比較特別的用於呈現靜態內容的部件——dcc.Markdown()
,它的children
引數接受markdown
程式碼,並自動在網頁中呈現出渲染後的效果,其主要引數如下:
children:字元型
markdown
原始碼dangerously_allow_html:bool型,用於設定是否允許解析出
markdown
原始碼中的html程式碼並渲染,預設為False即不進行渲染dedent:bool型,用於設定是否忽略每行文字開頭的空格等空白字元,預設為True
效果如下:
app10.py
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
app = dash.Dash(__name__)
app.layout = html.Div(
dbc.Container(
[
dcc.Markdown('''
> 本文示例程式碼已上傳至我的`Github`倉庫[https://github.com/CNFeffery/DataScienceStudyNotes](https://github.com/CNFeffery/DataScienceStudyNotes)
# 1 簡介
這是我的系列教程**Python+Dash快速web應用開發**的第五期,在上一期的文章中,我們針對`Dash`中有關回撥的一些技巧性的特性進行了介紹,使得我們可以更愉快地為`Dash`應用編寫回撥互動功能。
而今天的文章作為**回撥互動**系統性內容的最後一期,我將帶大家get一些`Dash`中實際應用效果驚人的**高階回撥特性**,繫好安全帶,我們起飛~
<p align="center"><img src="https://img2020.cnblogs.com/blog/1344061/202102/1344061-20210207194037614-808613819.png" style="zoom:100%;" /></p>
''',
dangerously_allow_html=True,
dedent=False)
]
)
)
if __name__ == "__main__":
app.run_server(debug=True)
有了Markdown()
部件的加持,我們就可以在某些情況下直接利用markdown
快速編寫網頁,譬如編寫線上文件說明頁面~
3 利用Dash自制線上Markdown編輯器
在掌握了今天的教程所涉及知識之後,我們就可以自己動手書寫一些具有實際互動功能的介面,譬如自制一個線上Markdown編輯器。
思路很簡單,利用今天所學的Textarea()
部件的value
屬性作為回撥的Input()
,再將Markdown()
部件的children
元素作為回撥的Output()
,再略微美化一下佈局,便實現瞭如下的效果~
對應的程式碼如下:
app11.py
import dash
import dash_html_components as html
import dash_core_components as dcc
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
app = dash.Dash(__name__)
app.layout = html.Div(
dbc.Container(
dbc.Row(
[
dbc.Col(
dcc.Textarea(
id='md-input',
placeholder='請輸入你的markdown原始碼!',
style={
'width': '100%',
'height': '100%'
}
),
width=6,
style={
'padding-right': 0,
'border': 'border:5px solid red'
}
),
dbc.Col(
dcc.Markdown(id='md-output',
dangerously_allow_html=True,
style={
'position': 'absolute',
'width': '100%',
'height': '100%'
}),
width=6,
style={
'position': 'relative',
'overflow': 'auto',
'padding-left': 0
}
),
],
style={
'position': 'fixed',
'top': 0,
'bottom': 0,
'left': 0,
'right': 0
}
)
),
style={
'font-size': '2rem'
}
)
@app.callback(
Output('md-output', 'children'),
Input('md-input', 'value')
)
def online_markdown(raw_text):
return raw_text
if __name__ == '__main__':
app.run_server(debug=True)
以上就是本文的全部內容,我們將在下一篇教程中繼續探討Dash
中那些更加好用且功能更加豐富的靜態部件,敬請期待~ 也歡迎大家在評論區與我進行討論~