SimpleStart 是利用Python语言开发网页进行数据可视化的工具,和 Streamlit 相似,但是支持事件响应和数据驱动,使用更简单,本文将详细介绍它的使用.
什么是 SimpleStart?
SimpleStart 是 Streamlit 的替代工具,具有相似的功能,可以用 Python 快速制作网页和可视化数据。它提供了丰富的组件,支持多页面应用、事件响应和数据驱动。
SimpleStart 的主要特点:
- 事件响应:点击按钮不会导致整个页面重新刷新。
- 多页面应用:能够方便地从子目录甚至二级子目录自动创建多页面应用。
- 数据驱动:可以使用 Session 变量控制页面显示,变量变化会自动反映在页面上。
1.1 安装 SimpleStart
可以使用pip包管理器安装 Streamlit。在终端或命令提示符中运行以下命令:
pip3 install simplestart
如果安装成功,可以运行命令 ss -V 查看版本,如果命令 ss 和系统冲突,也可以执行 myss - V 或者 simplestart -V。
1.2 配置文件
SimpleStart 允许用户配置应用运行参数,文件显示方式等。在项目目录中创建system目录,并创建config.yaml文件,内容如下:
#这是应用的标题
title: "SimpleStart Demo"
#是否默认显示左侧边栏
show_sidebar: true
#是否显示顶部栏
show_header: false
app_bar_height: 50 ##default is 64
#是否显示底部栏
show_footer: false
app_footer_height: 60 ### default is 44
#主页是否占满横向空间
wide_screen_mode : false
1.3 运行 SimpleStart 应用
如果需要运行用户的py文件,在终端或命令提示符中运行:
ss your_app.py
Note: 如果 ss 命令和系统有冲突,也可以换成 myss 或者 simplestart 例如
myss your_app.py
simplestart your_app.py
默认端口是8000, 可以指定端口,例如
ss your_app.py --port 8080
2.1 显示文本
SimpleStart 提供了 markdown, text, html 等显示文本的方式。 ss.markdown:支持html, emoji等,不支持javascript,可以提供各种格式的markdown内容。 代码演示
import simplestart as ss
ss.markdown("# Heading 1")
ss.markdown("## Heading 2")
ss.markdown("### Heading 3")
其它文本方法比如 ss.html 、 ss.text 也相对简单,就是显示html格式文本和普通文本,点击可以查看相关在线文档。
2.2 显示图像
ss.image: 用来显示图像,支持网络路径、本地路径、PIL.image/OpenCV image、和 ByteIO 内存图像的显示,并且支持多种Fit 模式,也可以为图像添加边框和标题。
代码演示
import simplestart as ss
from PIL import Image
#本地图片
ss.image("./test1.png")
#网络图片
myimg = ss.image("https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg")
#PIL image
image = Image.open('./media/image/dalao.jpeg')
ss.image(image)
#或者修改已有的图像
myimg.image = image
2.3 显示表格
ss.table 显示 Pandas DataFrame 格式的表格数据, 支持排序、索引、查找、和是否可选择、可编辑、显示表格线、以及设置宽度、高度等。
代码演示
import simplestart as ss
def current_change(state, value):
ss.session["row_selected"] = value["index"]
def selection_change(state, value):
ss.session["selection_change"] = value["selected"]
data = {'name': ['Alice', 'Bob', 'Charlie'],
'age': [25, 30, 35],
'city': ['New York', 'San Francisco', 'Los Angeles']}
df = pd.DataFrame(data)
ss.table(df, handlers={"current-change":current_change, "selection-change":selection_change})
ss.markdown("#### Events")
ss.markdown("Row selected: @row_selected")
ss.markdown("Selection changed: @selection_change")
def onPageLoad():
ss.session["row_selected"] = ''
ss.session["selection_change"] = ''
此外,通过 ss.sqlite 还可以从 sqlite 数据库中提取表格。
2.4 显示图表
ss.pyplot: 可以用来显示 matplotlib 绘制出来的图表。
代码演示
import streamsync as ss
import seaborn as sns
import matplotlib as mpl
import matplotlib.pyplot as plt
#画散点图
sns.set_style("whitegrid")
tips = sns.load_dataset("tips", data_home=data_home)
sns.scatterplot(x="total_bill", y="tip", data=tips)
plt.show()
fig = plt.gcf()
ss.pyplot(fig, style="border:1px solid gray; width:600px")
另外它提供了一个使用 Bokeh 的例子,可以实现交互式图表显示。
这段在 Bokeh 图表外部使用了 ss.slider 滑动组件,实现了图表的交互。代码
2.5 其它显示
SimpleStart 在内容显示方面还提供了通用显示方法 ss.write , 可以提供类似 print 的方式,例如
#...
students = ["Jane", "Smith", "Tom"]
ss.write("the name is ", students, "### hello", df)
可以输出文字、数字、数组、表格、图像等墅居。
其它内容显示还包括视频、音频、消息提示等, 参见 ss.video, ss.audio, ss.message
3.1 按钮
代码演示
import simplestart as ss
def myclick(event):
ss.message("You clicked")
ss.button("Dafault", onclick = myclick)
ss.button("Outlined", type="outlined", color="primary")
ss.button("Flat", type="flat", color="cyan", icon="mdi-open-in-new")
3.2 复选框
ss.checkbox: 复选框函数,有3个参数,标题、默认选中状态值、回调函数,也可以通过 ss.checkbox 变量直接获取或者设置选中状态。
代码演示
import simplestart as ss
def onchange(event):
ss.message(event.value)
ss.checkbox("checkme", onchange = onchange)
3.3 单选框
ss.radio: 单选框函数,主要参数有标题、选项数组、默认选项值或索引、选项改变回调函数等。
import simplestart as ss
def onchange(event):
ss.write(event.value, event.index)
options = ["Option 1", "Option 2", "Option 3"]
myradio = ss.radio(options, label = "### my radio1", index = 0, onchange = onchange)
3.4 下拉框
ss.selectbox: 创建下拉框,用户可以从选项中选择一个,主要参考有标题、下拉选项数组、默认选择值或索引以及选项改变回调函数。
import simplestart as ss
options = ["option1","option2", "option3"]
def selchange(event):
ss.session["select_value"] = event.value
ss.session["select_index"] = select1.index
ss.write("info value:@select_value index:@select_index")
select1 = ss.selectbox(options, index=0, onchange = selchange)
3.5 滑动拉杆
ss.slider: 创建一个滑块,用户可以在某个范围内选择一个值,主要参数有最小值、最大值、默认值和用户选择值。
代码演示
import simplestart as ss
info = ss.text("number")
def onchange(state, value):
info.text = value
ss.slider(500, 0, 1000, onchange = onchange)
3.6 菜单
**[ss.menu] 可以创建菜单项,方便导航,主要参数有菜单项、是否是水平菜单、回调函数等。
先看效果
代码演示
import simplestart as ss
data = [
{'index': '1', 'title': 'Processing Center', 'icon':'mdi-home'},
{'type': 'spacer'}, #add spacer
{
'index': '2',
'title': 'Workspace',
'icon' : 'mdi-plus',
'subItems': [
{'index': '2-1', 'title': 'item one'},
{'index': '2-2', 'title': 'item two'},
{'index': '2-3', 'title': 'item three'},
{
'index': '2-4',
'title': 'item four',
'subItems': [
{'index': '2-4-1', 'title': 'item one'},
{'index': '2-4-2', 'title': 'item two'},
{'index': '2-4-3', 'title': 'item three'},
],
},
],
},
{'index': '3', 'title': 'Info', 'disabled': True, 'icon':'mdi-cancel'},
{'index': '4', 'title': 'Orders', 'icon':'mdi-wrench'},
]
def menu_select(event):
print("menu1")
ss.message(event.data["keyPath"])
ss.md("### Horiontal Menu")
ss.menu(data, direction = "horizontal", onselect = menu_select)
ss.space()
ss.md("### Vertical Menu")
ss.menu(data, direction = "vertical", dark = True, onselect = menu_select)
主要是定义菜单项数据,然后在菜单点击事件中进行处理。
3.7 其它交互组件
其它交互组件还包括 对话框 ss.dialog、下载链接 ss.link 、下拉展开 ss.expander 、上传组件 ss.upload 等。
SimpleStart 提供事件响应,例如按钮的点击、下拉框的选择、文本框的输入都会触发事件,用户可以在事件里处理自己的逻辑。 这些事件响应函数都有一个 event 参数, 默认的属性有 event.value, 或者 event.index。
我们以按钮为例,它有一个 onclick 事件响应参数,例如
import simplestart as ss
def myclick(event): #这里event也可以不填
ss.message("you click")
ss.button("button", onclick = myclick)
当有很多按钮时,可以将所有逻辑集中到一个事件处理函数中,而不需要为每个按钮单独编写事件处理程序,这样可以使代码更加简洁明了。甚至可以将页面上所有组件的事件处理(包括按钮、选项卡、文本输入等)都集中在一个函数中。实现方法是,在创建组件时,添加一个 eventTag 参数,内容可以自定义。在事件响应时,SimpleStart 会将这个值赋给事件对象,通过 event.tag,用户可以获取该值并处理相应的逻辑。例如:
import simplestart as ss
def myhandler(event):
if event.tag == "button1":
ss.message("hi")
#... 你的逻辑代码1
elif event.tag == "button2":
ss.message("hi")
#... 你的逻辑代码2
elif event.tag == "text_change1":
ss.message(event.value)
#... 你的逻辑代码3
else:
ss.message("hi")
ss.button("button1", onclick = myhander, eventTag = "button1")
ss.button("button2", onclick = myhander, eventTag = "button2")
ss.text_input("initial text", onchange = myhander, eventTag = "text_change1")
在 SimpleStart 中,改变组件的显示值除了在创建时定义,和利用变量改变组件的属性,例如:
import simplestart as ss
mytext = ss.text("Hello, world")
def myclick(event):
mytext.text = "Amazing"
ss.button("mybutton", onclick = myclick
此外,可以通过直接修改变量来实现界面的实时响应。只需在显示文本中以 @ 符号开头来引用会话变量,例如 @variable, variable 对应会话变量 ss.session 。
代码演示
import simplestart as ss
mytext = ss.text("Hello, world. @feeling")
ss.session.feeling = "Amazing"
def myclick(event):
ss.session.feeling = "wanderful"
ss.button("button", onclick = myclick)
在上述代码中,初始显示为 “Hello, world. Amazing”,因为 @feeling 被会话变量 ss.session.feeling 的值替换。当点击按钮后,文本更新为 "Hello, world. Wonderful",这是因为在按钮事件中修改了 ss.session.feeling 的值。
这种机制使得组件能够自动响应变量的变化,实现了用户界面的动态性和交互性。这里 ss.session 中的会话变量可以任何地方修改,所以也可以用于页面间的数据传递。
SimpleStart 支持多页面应用。当您使用命令 ss your_code.py 启动 SimpleStart 时,your_code.py 为主文件,默认情况下是单页面应用。
若要实现多页面功能,请在当前目录下创建一个名为 pages 的子目录,然后在该目录中放置其他用户代码文件。系统会自动识别这些文件,并在左侧栏中显示所有文件的目录列表,方便用户进行导航和访问。
这种实现模式与 Streamlit 类似,均支持通过目录结构简化多页面应用的开发与管理。
在 SimpleStart 中,可以在 pages 子目录下创建嵌套的子目录,以支持更复杂的页面结构。假设您的文件结构如下:
-- app.py # 主页面代码
-- pages
-- test1.py # 页面1
-- test2.py # 页面2
-- sub1 # 子目录1
-- test3.py # 子页面3
-- sub2 # 子目录2
-- test4.py # 子页面4
在这个结构中:
app.py 是主文件。
- pages 子目录包含两个文件 test1.py 和 test2.py 作为直接页面。
- 在 pages 目录下,还可以创建子目录(如 sub1 和 sub2),并在这些子目录中放置其他页面文件(如 test3.py 和 test4.py)。
- SimpleStart 会自动识别这些文件和子目录,并在左侧栏中展示所有页面的目录列表,方便用户进行访问。
效果如图
还可以很方便地修改显示名称和排序。
更改显示名称
在 SimpleStart 中,可以自定义页面文件和目录的显示名称:
-
页面文件
-
在每个页面文件的第一行,使用三个 ### 后面跟一个空格和标题名。
-
这样设置后,该标题将出现在左侧目录栏中。
例如
### 这是主页面 import simplestart as ss #其它代码
-
目录名称
-
对于子目录(如 sub1 和 sub2),您需要在相应的目录中创建一个名为 folder.json 的文件。
-
在 folder.json 文件中填写目录的别名
-
这种设置将使得目录在左侧目录栏中显示为指定的别名
例如:
{"alias": "这是Sub1目录"}`
最后的页面效果
更改显示位置
默认情况下,页面文件和目录在左侧栏中的显示顺序是按照文件名的字母排序。如果您想更改显示顺序,可以在文件或目录名前添加三位数的排序序号。例如:
- 001 test2.py
- 002 test1.py
这样 test2.py 将排在 test1.py 前面显示。
请注意,这些序号不会出现在左侧栏目录中,仅用于控制排序顺序。通过这种方式,可以灵活调整页面和目录的显示顺序,以满足特定需求。
代码打开页面
ss.openpage: 用这个函数可以打开页面,参数名是 pagename, reload,分别表示页面名称,以及是否要重新打开,因为默认情况下,SimpleStart 对于打开过的页面,会直接显示保存的内容。
对于主页面, pagename 总是 "main", 对于子页面, pagename是不带"pages"的路径,不用带.py文件扩展名,比如
ss.openpage("main")
ss.openpage("test1")
ss.openpage("sub2/test4")
7.1 列布局
ss.columns: 将页面按照列分成几个部分,参数可以按照比例或者数组将页面分割。
import simplestart as ss
#按比例将页面划分为两列
cols1 = ss.columns(2, border = True)
with cols1[0]:
ss.text("First of two columns")
with cols1[1]:
ss.text("Second of two columns")
import simplestart as ss
#按照自定义数列,自动计算比例
cols1 = ss.columns([4,6], border = True)
with cols1[0]:
ss.text("First of two columns")
with cols1[1]:
ss.text("Second of two columns")
7.2 行与间距控制
ss.row: 行组件用于强制将其他组件在同一行内显示。 ss.spacer 间距控制可以改变行内组件的排列对齐方式。
这两个通常会组合在一起使用。
代码演示
import simplestart as ss
style = "background:#d3d3d354; padding:5px;"
ss.space()
ss.write("#### 1. Normal")
ss.space()
with ss.row(style=style):
ss.button("button1")
ss.button("button2")
ss.space()
ss.write("#### 2. Center")
ss.space()
with ss.row(style=style):
ss.spacer()
ss.button("button1")
ss.button("button2")
ss.spacer()
ss.space()
ss.write("#### 3. Right align")
ss.space()
with ss.row(style=style):
ss.spacer()
ss.button("button1")
ss.button("button2")
ss.space()
ss.write("#### 4. Right respectively")
ss.space()
with ss.row(style=style):
ss.spacer()
ss.button("button1")
ss.spacer()
ss.button("button2")
7.3 container 一般容器
ss.section 或者 ss.container: 用于创建一般容器,参数有标题、边框、颜色等
代码演示
import simplestart as ss
#api
def clear():
section.empty()
def write_something():
section.text("Hello, I am inside section 2")
#ui
with ss.section(title = "Section1", shadow = 10, border = True, rounded=True, width = "50%", height=300):
ss.text("This is inside the section 1")
7.4 标签页
ss.tabs: 以标签页的方式提供的容器。
代码演示:
import simplestart as ss
tabtitles = ["tab1", "tab2", "tab3"]
tabs = ss.tabs(tabtitles)
with tabs[0]:
ss.text("this is tab 1")
with tabs[1]:
ss.text("this is tab 2")
with tabs[2]:
ss.text("this is tab 3")
7.5 侧边栏
ss.sidebar: 侧边栏作为页面的辅助空间,可以放置一些控制元素,如按钮、滑块和选择框等。它提供了一个方便的界面,用户可以在不干扰主内容区域的情况下进行交互。
代码演示
import simplestart as ss
sidebar = ss.sidebar()
with sidebar:
ss.button("click")
ss.selectbox(["one", "two", "three"])
SimpleStart 还提供了对顶部和底部区域的定制化。
7.6 顶部和底部栏
顶部栏是应用顶部的header空间,底部栏是应用底部的footer空间,默认都是隐藏的,通过config.yaml 配置文件可以显示,默认高度分别是64px和44px, 可以修改。例如
#...
show_header: true
app_bar_height: 59 ##default is 64
show_footer: true
app_footer_height : 100 ##default is 44
config.yaml 文件的路径是 system/config.yaml, 相对于项目的根目录。
然后,创建 system/myheader.py 和 system/myfooter.py 两个代码文件,这里输出的内容,分别会显示在顶部和底部。
SimpleStart 还支持条件语句、自定义组件、模版等,可以参考在线文档和演示。
