创建一个多页面APP
在 附加功能 部分,我们介绍了多页面应用程序的相关内容,包括如何定义页面、构建以及运行多页面应用程序,以及在用户界面中进行页面之间的导航操作。您可以在我们的 多页面应用程序指南 中获取更多详细信息。
在本指南中,让我们将对多页面应用程序的理解付诸实践,将我们之前版本的 streamlit hello 应用程序转换为一个多页面应用程序!
动机
在 Streamlit 1.10.0 版本之前,streamlit hello 命令是一个包含大量内容的单页应用程序。由于不支持多页面功能,我们只好在侧边栏使用 st.selectbox 来选择要运行的内容。这些内容包括三个用于绘图、地图绘制和数据框展示的演示示例。
这就是代码和单页应用程序的 原始样子。
import streamlit as st
def intro():
import streamlit as st
st.write("# Welcome to Streamlit! ")
st.sidebar.success("Select a demo above.")
st.markdown(
"""
Streamlit is an open-source app framework built specifically for
Machine Learning and Data Science projects.
** Select a demo from the dropdown on the left** to see some examples
of what Streamlit can do!
### Want to learn more?
- Check out [streamlit.io](https://streamlit.io)
- Jump into our [documentation](https://docs.streamlit.io)
- Ask a question in our [community
forums](https://discuss.streamlit.io)
### See more complex demos
- Use a neural net to [analyze the Udacity Self-driving Car Image
Dataset](https://github.com/streamlit/demo-self-driving)
- Explore a [New York City rideshare dataset](https://github.com/streamlit/demo-uber-nyc-pickups)
"""
)
def mapping_demo():
import streamlit as st
import pandas as pd
import pydeck as pdk
from urllib.error import URLError
st.markdown(f"# {list(page_names_to_funcs.keys())[2]}")
st.write(
"""
This demo shows how to use
[`st.pydeck_chart`](https://docs.streamlit.io/develop/api-reference/charts/st.pydeck_chart)
to display geospatial data.
"""
)
@st.cache_data
def from_data_file(filename):
url = (
"http://raw.githubusercontent.com/streamlit/"
"example-data/master/hello/v1/%s" % filename
)
return pd.read_json(url)
try:
ALL_LAYERS = {
"Bike Rentals": pdk.Layer(
"HexagonLayer",
data=from_data_file("bike_rental_stats.json"),
get_position=["lon", "lat"],
radius=200,
elevation_scale=4,
elevation_range=[0, 1000],
extruded=True,
),
"Bart Stop Exits": pdk.Layer(
"ScatterplotLayer",
data=from_data_file("bart_stop_stats.json"),
get_position=["lon", "lat"],
get_color=[200, 30, 0, 160],
get_radius="[exits]",
radius_scale=0.05,
),
"Bart Stop Names": pdk.Layer(
"TextLayer",
data=from_data_file("bart_stop_stats.json"),
get_position=["lon", "lat"],
get_text="name",
get_color=[0, 0, 0, 200],
get_size=15,
get_alignment_baseline="'bottom'",
),
"Outbound Flow": pdk.Layer(
"ArcLayer",
data=from_data_file("bart_path_stats.json"),
get_source_position=["lon", "lat"],
get_target_position=["lon2", "lat2"],
get_source_color=[200, 30, 0, 160],
get_target_color=[200, 30, 0, 160],
auto_highlight=True,
width_scale=0.0001,
get_width="outbound",
width_min_pixels=3,
width_max_pixels=30,
),
}
st.sidebar.markdown("### Map Layers")
selected_layers = [
layer
for layer_name, layer in ALL_LAYERS.items()
if st.sidebar.checkbox(layer_name, True)
]
if selected_layers:
st.pydeck_chart(
pdk.Deck(
map_style="mapbox://styles/mapbox/light-v9",
initial_view_state={
"latitude": 37.76,
"longitude": -122.4,
"zoom": 11,
"pitch": 50,
},
layers=selected_layers,
)
)
else:
st.error("Please choose at least one layer above.")
except URLError as e:
st.error(
"""
**This demo requires internet access.**
Connection error: %s
"""
% e.reason
)
def plotting_demo():
import streamlit as st
import time
import numpy as np
st.markdown(f'# {list(page_names_to_funcs.keys())[1]}')
st.write(
"""
This demo illustrates a combination of plotting and animation with
Streamlit. We're generating a bunch of random numbers in a loop for around
5 seconds. Enjoy!
"""
)
progress_bar = st.sidebar.progress(0)
status_text = st.sidebar.empty()
last_rows = np.random.randn(1, 1)
chart = st.line_chart(last_rows)
for i in range(1, 101):
new_rows = last_rows[-1, :] + np.random.randn(5, 1).cumsum(axis=0)
status_text.text("%i%% Complete" % i)
chart.add_rows(new_rows)
progress_bar.progress(i)
last_rows = new_rows
time.sleep(0.05)
progress_bar.empty()
# Streamlit widgets automatically run the script from top to bottom. Since
# this button is not connected to any other logic, it just causes a plain
# rerun.
st.button("Re-run")
def data_frame_demo():
import streamlit as st
import pandas as pd
import altair as alt
from urllib.error import URLError
st.markdown(f"# {list(page_names_to_funcs.keys())[3]}")
st.write(
"""
This demo shows how to use `st.write` to visualize Pandas DataFrames.
(Data courtesy of the [UN Data Explorer](http://data.un.org/Explorer.aspx).)
"""
)
@st.cache_data
def get_UN_data():
AWS_BUCKET_URL = "http://streamlit-demo-data.s3-us-west-2.amazonaws.com"
df = pd.read_csv(AWS_BUCKET_URL + "/agri.csv.gz")
return df.set_index("Region")
try:
df = get_UN_data()
countries = st.multiselect(
"Choose countries", list(df.index), ["China", "United States of America"]
)
if not countries:
st.error("Please select at least one country.")
else:
data = df.loc[countries]
data /= 1000000.0
st.write("### Gross Agricultural Production ($B)", data.sort_index())
data = data.T.reset_index()
data = pd.melt(data, id_vars=["index"]).rename(
columns={"index": "year", "value": "Gross Agricultural Product ($B)"}
)
chart = (
alt.Chart(data)
.mark_area(opacity=0.3)
.encode(
x="year:T",
y=alt.Y("Gross Agricultural Product ($B):Q", stack=None),
color="Region:N",
)
)
st.altair_chart(chart, use_container_width=True)
except URLError as e:
st.error(
"""
**This demo requires internet access.**
Connection error: %s
"""
% e.reason
)
page_names_to_funcs = {
"—": intro,
"Plotting Demo": plotting_demo,
"Mapping Demo": mapping_demo,
"DataFrame Demo": data_frame_demo
}
demo_name = st.sidebar.selectbox("Choose a demo", page_names_to_funcs.keys())
page_names_to_funcs[demo_name]()
请注意这个文件的大小是多么之大!每个应用程序的“页面”都是以函数的形式编写,而选择框则用于选择要显示的页面。随着我们应用程序的不断发展,维护代码需要付出大量的额外工作。此外,由于 st.selectbox 用户界面的限制,我们只能选择要运行的“页面”,无法使用 st.set_page_config 自定义每个页面的标题,并且也无法通过 URL 在页面之间进行导航。
将现有应用程序转换为多页面应用程序
既然我们已经发现了单页面应用程序的局限性,那么我们该如何解决这个问题呢?凭借上一节所获得的知识,我们当然可以将现有的应用程序转换为多页面应用程序!从总体上看,我们需要执行以下步骤:
在“入口文件”(
hello.py)所在的同一文件夹中创建一个新的pages文件夹将我们的入口文件重命名为
hello.py,以便侧边栏中的标题为大写形式在
pages文件夹内创建三个新文件:pages/1__Plotting_Demo.pypages/2__Mapping_Demo.pypages/3__DataFrame_Demo.py
将
plotting_demo、mapping_demo和data_frame_demo的内容移动到步骤 3 中创建的相应新文件中运行
streamlit run Hello.py以查看您新转换的多页面应用程序!
现在,让我们逐步查看整个过程中的每个步骤,并查看代码中相应的更改。
创建入口文件
# Hello.py
import streamlit as st
st.set_page_config(
page_title="Hello",
page_icon="",
)
st.write("# Welcome to Streamlit! ")
st.sidebar.success("Select a demo above.")
st.markdown(
"""
Streamlit is an open-source app framework built specifically for
Machine Learning and Data Science projects.
** Select a demo from the sidebar** to see some examples
of what Streamlit can do!
### Want to learn more?
- Check out [streamlit.io](https://streamlit.io)
- Jump into our [documentation](https://docs.streamlit.io)
- Ask a question in our [community
forums](https://discuss.streamlit.io)
### See more complex demos
- Use a neural net to [analyze the Udacity Self-driving Car Image
Dataset](https://github.com/streamlit/demo-self-driving)
- Explore a [New York City rideshare dataset](https://github.com/streamlit/demo-uber-nyc-pickups)
"""
)
我们将入口文件重命名为hello.py,这样侧边栏中的标题就会首字母大写,并且只包含介绍页面的代码。此外,我们还可以通过调用 st.set_page_config 来自定义页面标题和网站图标——它会在浏览器标签页中显示出来。我们还可以为每个页面都进行这样的设置!

请注意,侧边栏中并未显示页面标签,因为我们尚未创建任何页面。
创建多个页面
在此需要注意以下几点:
我们可以通过在每个 Python 文件的开头添加数字来更改 MPA 中页面的排列顺序。如果我们在文件名前添加一个 1,Streamlit 将会把该文件放在列表中的首位。
每个 Streamlit 应用的名称由文件名决定,所以要更改应用名称,就需要更改文件名!
我们还可以在文件名中添加表情符号,这些表情符号会在我们的 Streamlit 应用中显示出来。
每个页面都有其自己的 URL,由文件名定义。
下面来看看我们是如何完成这一切的!对于每个新页面,我们在“pages”文件夹中创建一个新的文件,并在其中添加相应的演示代码。
# pages/1__Plotting_Demo.py
import streamlit as st
import time
import numpy as np
st.set_page_config(page_title="Plotting Demo", page_icon="")
st.markdown("# Plotting Demo")
st.sidebar.header("Plotting Demo")
st.write(
"""This demo illustrates a combination of plotting and animation with
Streamlit. We're generating a bunch of random numbers in a loop for around
5 seconds. Enjoy!"""
)
progress_bar = st.sidebar.progress(0)
status_text = st.sidebar.empty()
last_rows = np.random.randn(1, 1)
chart = st.line_chart(last_rows)
for i in range(1, 101):
new_rows = last_rows[-1, :] + np.random.randn(5, 1).cumsum(axis=0)
status_text.text("%i%% Complete" % i)
chart.add_rows(new_rows)
progress_bar.progress(i)
last_rows = new_rows
time.sleep(0.05)
progress_bar.empty()
# Streamlit widgets automatically run the script from top to bottom. Since
# this button is not connected to any other logic, it just causes a plain
# rerun.
st.button("Re-run")

# pages/2__Mapping_Demo.py
import streamlit as st
import pandas as pd
import pydeck as pdk
from urllib.error import URLError
st.set_page_config(page_title="Mapping Demo", page_icon="")
st.markdown("# Mapping Demo")
st.sidebar.header("Mapping Demo")
st.write(
"""This demo shows how to use
[`st.pydeck_chart`](https://docs.streamlit.io/develop/api-reference/charts/st.pydeck_chart)
to display geospatial data."""
)
@st.cache_data
def from_data_file(filename):
url = (
"http://raw.githubusercontent.com/streamlit/"
"example-data/master/hello/v1/%s" % filename
)
return pd.read_json(url)
try:
ALL_LAYERS = {
"Bike Rentals": pdk.Layer(
"HexagonLayer",
data=from_data_file("bike_rental_stats.json"),
get_position=["lon", "lat"],
radius=200,
elevation_scale=4,
elevation_range=[0, 1000],
extruded=True,
),
"Bart Stop Exits": pdk.Layer(
"ScatterplotLayer",
data=from_data_file("bart_stop_stats.json"),
get_position=["lon", "lat"],
get_color=[200, 30, 0, 160],
get_radius="[exits]",
radius_scale=0.05,
),
"Bart Stop Names": pdk.Layer(
"TextLayer",
data=from_data_file("bart_stop_stats.json"),
get_position=["lon", "lat"],
get_text="name",
get_color=[0, 0, 0, 200],
get_size=15,
get_alignment_baseline="'bottom'",
),
"Outbound Flow": pdk.Layer(
"ArcLayer",
data=from_data_file("bart_path_stats.json"),
get_source_position=["lon", "lat"],
get_target_position=["lon2", "lat2"],
get_source_color=[200, 30, 0, 160],
get_target_color=[200, 30, 0, 160],
auto_highlight=True,
width_scale=0.0001,
get_width="outbound",
width_min_pixels=3,
width_max_pixels=30,
),
}
st.sidebar.markdown("### Map Layers")
selected_layers = [
layer
for layer_name, layer in ALL_LAYERS.items()
if st.sidebar.checkbox(layer_name, True)
]
if selected_layers:
st.pydeck_chart(
pdk.Deck(
map_style="mapbox://styles/mapbox/light-v9",
initial_view_state={
"latitude": 37.76,
"longitude": -122.4,
"zoom": 11,
"pitch": 50,
},
layers=selected_layers,
)
)
else:
st.error("Please choose at least one layer above.")
except URLError as e:
st.error(
"""
**This demo requires internet access.**
Connection error: %s
"""
% e.reason
)

# pages/3__DataFrame_Demo.py
import streamlit as st
import pandas as pd
import altair as alt
from urllib.error import URLError
st.set_page_config(page_title="DataFrame Demo", page_icon="")
st.markdown("# DataFrame Demo")
st.sidebar.header("DataFrame Demo")
st.write(
"""This demo shows how to use `st.write` to visualize Pandas DataFrames.
(Data courtesy of the [UN Data Explorer](http://data.un.org/Explorer.aspx).)"""
)
@st.cache_data
def get_UN_data():
AWS_BUCKET_URL = "http://streamlit-demo-data.s3-us-west-2.amazonaws.com"
df = pd.read_csv(AWS_BUCKET_URL + "/agri.csv.gz")
return df.set_index("Region")
try:
df = get_UN_data()
countries = st.multiselect(
"Choose countries", list(df.index), ["China", "United States of America"]
)
if not countries:
st.error("Please select at least one country.")
else:
data = df.loc[countries]
data /= 1000000.0
st.write("### Gross Agricultural Production ($B)", data.sort_index())
data = data.T.reset_index()
data = pd.melt(data, id_vars=["index"]).rename(
columns={"index": "year", "value": "Gross Agricultural Product ($B)"}
)
chart = (
alt.Chart(data)
.mark_area(opacity=0.3)
.encode(
x="year:T",
y=alt.Y("Gross Agricultural Product ($B):Q", stack=None),
color="Region:N",
)
)
st.altair_chart(chart, use_container_width=True)
except URLError as e:
st.error(
"""
**This demo requires internet access.**
Connection error: %s
"""
% e.reason
)

在我们新增了更多页面之后,现在就可以在下面的最后一步中将所有内容整合在一起了。
运行多页面应用程序
要运行您刚刚转换完成的多页面应用程序,请执行以下操作:
运行以下命令:streamlit run Hello.py
!现在,hello.py 脚本就相当于你的应用程序的主页面了,而 Streamlit 在pages文件夹中找到的其他脚本也会出现在侧边栏出现的新页面选择器中。
下一步
恭喜! 如果您已经读到这里,那么您很可能已经学会了如何创建单页和多页应用程序。接下来您要走的路完全取决于您的创造力!我们非常期待看到您现在所构建的作品,因为现在为您的应用程序添加更多页面比以往任何时候都更加容易。试着为刚刚构建的应用程序添加更多页面作为练习。另外,也请访问论坛,与 Streamlit 社区一起展示您的多页应用程序吧!
以下是一些能帮助您入门的资源:
在 Streamlit 的社区云平台上免费部署您的应用程序。
在我们的社区论坛上提出问题或分享您的多页面应用程序。
查看关于多页面应用程序的文档。
阅读有关缓存、主题设置以及为应用程序添加状态性等内容的说明。
浏览我们的 API 参考,以获取每个 Streamlit 命令的示例。
创建一个多页面APP的更多相关文章
- 一个先进的App框架:使用Ionic创建一个简单的APP
原文 http://www.w3cplus.com/mobile/building-simple-app-using-ionic-advanced-html5-mobile-app-framewor ...
- 为Go Web App 创建一个主页面
原文地址 大多数web app都有一个相同的布局.这个布局可能包含一个header或者footer,甚至可能包含一个导航菜单.Go的标准库提供一个简单的方式来创建这些基本元素,通过被不同的页面重 ...
- 用 JSQMessagesViewController 创建一个 iOS 聊天 App - 第 2 部分
原文链接 : Create an iOS Chat App using JSQMessagesViewController – Part 2 原文作者 : Mariusz Wisniewski 译者 ...
- 20 如何通过pycharm快速的创建一个html页面
1.打开pycharm并且新建一个html页面,如下图所示. 2.删除html页面中默认的内容,之后在页面中输入!,之后点击tab即可完成一个html页面的框架新增.
- 使用ionic framework创建一个简单的APP
ionic是一个以cordova为基础的html5前端框架,功能强大,能够快速做出与原生开发相似的应用. 一,安装和配置 1,安装(前提:cordova环境配置完成) npm install -g i ...
- 如何创建一个asp页面
Active Server Pages(ASP)文件是以 .asp 为扩展名的文本文件,这个文本文件可以包括下列部分的任意组合: 文本 HTML 标记 ASP 脚本命令 创建 .asp 文件非常容易. ...
- 创建一个 Spring Boot 项目,你会几种方法?
我最早是 2016 年底开始写 Spring Boot 相关的博客,当时使用的版本还是 1.4.x ,文章发表在 CSDN 上,阅读量最大的一篇有 42W+,如下图: 2017 年由于种种原因,就没有 ...
- ng 通过factory方法来创建一个心跳服务
<!DOCTYPE html> <html ng-app="myApp"> <head lang="en"> <met ...
- Maven(三)使用 IDEA 创建一个 Maven 项目
利用 IDEA 创建一个 Maven 项目 创建 Maven 项目 选择 File --> New --> Project 选中 Maven 填写项目信息 选择工作空间 目录结构 ├─sr ...
- flutter系列之:创建一个内嵌的navigation
目录 简介 搭建主Navigator 构建子路由 总结 简介 我们在flutter中可以使用Navigator.push或者Navigator.pushNamed方法来向Navigator中添加不同的 ...
随机推荐
- Wireshark 的抓包和分析,看这篇就够了!
原文:Wireshark 的抓包和分析,看这篇就够了!
- doctrine执行原生sql并直接返回结果集
直接返回结果集: getConnection反回了\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\Connection.php接口的实现,所以Connec ...
- 探秘Transformer系列之(32)--- Lookahead Decoding
探秘Transformer系列之(32)--- Lookahead Decoding 目录 探秘Transformer系列之(32)--- Lookahead Decoding 0x00 概述 0x0 ...
- 原生JS表格数据常用总结
主要是在数据报表这块, 做了好几年发现, 其实用户最终想要看的并不是酷炫的BI大屏, 而是最基础也是最复杂的 中国式报表. 更多就是倾向于从表格中去获取数据信息, 最简单的就是最好的, 于是还是来总结 ...
- ASP.NET Core知识积累
1.[HttpGet(Name="xxxx")] 当在 ASP.NET Core 中的控制器中使用 [HttpGet(Name = "GetWeatherForecast ...
- 航空货运系统总结性Blog
前言 本次题目集以航空运送货物为背景,设计航空货物管理系统,主要考察对类设计的把握是否合理还有对继承和多态的使用,能否设计出符合标准的类,是否充分理解对面向对象六大设计原则(SRP,OCP,LSP,D ...
- 20244104陈思淼 《Python程序设计》实验三报告
课程:<Python程序设计> 班级:2441 姓名:陈思淼 学号:20244104 实验教师:王志强 实验日期:20254月20日 必修/选修: 公选课 1.实验内容 创建服务端和客户端 ...
- python 利用librosa库变声,声音变速
wav文件可自定义,将wav文件放置在代码的同一目录下 文件要改名为gg. wav 声音变速: import librosa y,sr = librosa.load("gg.wav" ...
- 以RRT为例分析创新点的产生
1.找到基本算法的问题 1.1 喂文章和专利给GPT并分析提出的问题 1.2 整理问题 分析当前问题属于基本算法的那个阶段 2.1 固定参数问题:以双向RRT为例子:步长.采样方向.局部优化范围.交换 ...
- Web前端入门第 63 问:JavaScript 图解 for 循环执行顺序
神奇的 for 循环代码执行顺序并不是按照代码书写顺序执行,这就导致在看很多程序算法的时候,会有那么一点打脑壳. for 语法 for 循环的语法很简单,重点是小括号里面的三个部分,这三部分的执行顺序 ...