1. NiceGui简介
1.1 什么是NiceGui?
NiceGui是一个基于Python的轻量级Web界面库,它允许开发者使用简单的Python代码快速构建交互式Web界面。与传统的Web框架不同,NiceGui不需要你了解HTML、CSS或JavaScript,只需使用Python代码就能创建功能丰富的Web应用。
from nicegui import ui
ui.label('Hello, NiceGui!')
ui.button('点击我', on_click=lambda: ui.notify('按钮被点击了!'))
ui.run()
1.2 NiceGui的特点
- 纯Python:无需前端知识,只需Python
- 即时反馈:代码修改后界面自动更新
- 丰富的组件:按钮、输入框、图表等常用组件一应俱全
- 响应式设计:自动适应不同屏幕尺寸
- 简单部署:可轻松部署为独立应用或集成到现有Web服务
1.3 NiceGui的优势
表1 NiceGui与其他Web框架对比
|
特性 |
NiceGui |
Flask/Django |
Streamlit |
|
学习曲线 |
低 |
中高 |
中 |
|
前端知识要求 |
无 |
需要 |
无 |
|
开发速度 |
快 |
慢 |
快 |
|
定制灵活性 |
中 |
高 |
低 |
|
适合场景 |
工具类应用 |
复杂Web应用 |
数据展示 |
NiceGui架构示意图:
graph TD
A[Python代码] --> B[NiceGui库]
B --> C[Web界面]
C --> D[用户交互]
D --> B
B --> E[浏览器]
2. NiceGui基础
2.1 安装与设置
安装NiceGui超级简单,只需使用pip:
pip install nicegui
2.2 第一个NiceGui应用
创建一个基本的NiceGui应用只需要几行代码:
from nicegui import ui
# 创建一个标签
ui.label('欢迎使用NiceGui!')
# 创建一个按钮
ui.button('点击我', on_click=lambda: ui.notify('你好!'))
# 运行应用
ui.run()
运行这段代码会自动打开浏览器显示你的应用界面。
2.3 基本组件原型
NiceGui的大多数组件遵循类似的语法模式:
ui.component_name(
value=None, # 组件值
label='', # 显示标签
on_change=None, # 值改变时的回调
**kwargs # 其他特定属性
)
2.4 常用组件介绍
2.4.1 文本显示
ui.label('普通文本') # 普通文本
ui.markdown('**Markdown**支持') # 支持Markdown格式
ui.html('<span>HTML内容</span>') # 直接使用HTML
2.4.2 输入控件
name = ui.input('请输入姓名', placeholder='张三')
password = ui.input('密码', password=True, password_toggle_button=True)
slider = ui.slider(min=0, max=100, value=50, step=1)
checkbox = ui.checkbox('我同意条款')
2.4.3 按钮与交互
def handle_click():
ui.notify(f'你点击了按钮!')
ui.button('点击我', on_click=handle_click)
2.4.4 布局组件
with ui.row(): # 水平排列
ui.button('按钮1')
ui.button('按钮2')
with ui.column(): # 垂直排列
ui.label('项目1')
ui.label('项目2')
2.4.5 数据展示
# 表格
table = ui.table({
'column_defs': [
{'headerName': "姓名", 'field': "name"},
{'headerName': "年龄", 'field': "age"},
],
'row_data': [
{'name': '张三', 'age': 25},
{'name': '李四', 'age': 30},
]
})
# 图表
chart = ui.chart({
'title': {'text': '示例图表'},
'series': [{'data': [1, 2, 3, 4, 5]}]
})
3. NiceGui进阶用法
3.1 响应式编程
NiceGui支持响应式编程,当数据变化时界面会自动更新:
from nicegui import ui
count = 0
def increment():
global count
count += 1
counter.set_text(f'计数: {count}')
ui.button('增加', on_click=increment)
counter = ui.label(f'计数: {count}')
ui.run()
3.2 状态管理
对于更复杂的状态管理,可以使用app.storage:
from nicegui import app
# 用户级存储
app.storage.user['count'] = 0
def increment():
app.storage.user['count'] += 1
counter.set_text(f'计数: {app.storage.user["count"]}')
ui.button('增加', on_click=increment)
counter = ui.label(f'计数: {app.storage.user["count"]}')
ui.run()
3.3 页面路由
NiceGui支持多页面应用:
from nicegui import ui
@ui.page('/page1')
def page1():
ui.label('这是页面1')
ui.link('去页面2', '/page2')
@ui.page('/page2')
def page2():
ui.label('这是页面2')
ui.link('返回页面1', '/page1')
ui.run()
3.4 自定义样式
你可以轻松地为组件添加自定义样式:
ui.label('红色文本').style('color: red; font-size: 20px;')
ui.button('大按钮').classes('text-xl p-4')
4. 应用举例
4.1 待办事项应用
from nicegui import ui
todos = []
new_todo = ui.input(placeholder='输入新任务')
def add_todo():
if new_todo.value:
todos.append(new_todo.value)
todo_list.refresh()
new_todo.value = ''
@ui.refreshable
def todo_list():
for todo in todos:
with ui.row().classes('items-center'):
ui.checkbox()
ui.label(todo)
ui.button('删除', on_click=lambda t=todo: remove_todo(t)).props('flat')
def remove_todo(todo):
todos.remove(todo)
todo_list.refresh()
ui.button('添加', on_click=add_todo)
todo_list()
ui.run()
4.2 数据可视化仪表盘
from nicegui import ui
import random
# 创建仪表盘布局
with ui.grid(columns=2):
# 折线图
line_chart = ui.chart({
'title': {'text': '随机数据趋势'},
'series': [{'data': [random.randint(0, 100) for _ in range(10)]}]
}).classes('w-full h-64')
# 饼图
pie_chart = ui.chart({
'title': {'text': '数据分布'},
'series': [{
'type': 'pie',
'data': [
{'name': 'A', 'value': 35},
{'name': 'B', 'value': 30},
{'name': 'C', 'value': 25},
{'name': 'D', 'value': 10},
]
}]
}).classes('w-full h-64')
# 刷新按钮
def refresh_data():
line_chart.options['series'][0]['data'] = [random.randint(0, 100) for _ in range(10)]
line_chart.update()
pie_chart.options['series'][0]['data'] = [
{'name': 'A', 'value': random.randint(20, 40)},
{'name': 'B', 'value': random.randint(20, 40)},
{'name': 'C', 'value': random.randint(20, 40)},
{'name': 'D', 'value': random.randint(5, 15)},
]
pie_chart.update()
ui.button('刷新数据', on_click=refresh_data)
ui.run()
4.3 文件上传与处理
from nicegui import ui
import pandas as pd
import io
# 文件上传组件
upload = ui.upload(label='上传CSV文件',
auto_upload=True,
on_upload=lambda e: handle_upload(e))
# 结果显示区域
result_table = ui.table({
'column_defs': [],
'row_data': []
}).classes('w-full')
def handle_upload(e):
# 读取上传的文件
content = e.content.read()
df = pd.read_csv(io.BytesIO(content))
# 更新表格显示
result_table.options['column_defs'] = [
{'headerName': col, 'field': col} for col in df.columns
]
result_table.options['row_data'] = df.to_dict('records')
result_table.update()
ui.notify(f'成功加载 {len(df)} 行数据')
ui.run()
5. 内置模块
5.1 UI组件模块
NiceGui提供了丰富的内置UI组件:
表2 常用UI组件一览
|
组件名称 |
描述 |
常用属性 |
|
ui.button |
按钮 |
label, on_click, icon |
|
ui.input |
文本输入框 |
label, placeholder, value, on_change |
|
ui.checkbox |
复选框 |
label, value, on_change |
|
ui.select |
下拉选择框 |
options, value, on_change |
|
ui.slider |
滑块 |
min, max, value, step, on_change |
|
ui.table |
数据表格 |
column_defs, row_data |
|
ui.chart |
图表 |
options |
|
ui.markdown |
Markdown文本 |
content |
|
ui.html |
原始HTML内容 |
content |
5.2 布局模块
NiceGui提供了灵活的布局选项:
# 网格布局
with ui.grid(columns=3):
for i in range(9):
ui.button(f'按钮 {i+1}')
# 卡片布局
with ui.card().classes('w-64'):
ui.label('卡片标题').classes('text-xl')
ui.separator()
ui.label('卡片内容')
with ui.row():
ui.button('确定')
ui.button('撤销')
5.3 工具模块
NiceGui还提供了一些实用工具:
# 通知消息
ui.notify('操作成功!', type='positive')
# 对话框
def show_dialog():
with ui.dialog() as dialog:
with ui.card():
ui.label('确认删除吗?')
with ui.row():
ui.button('确认', on_click=dialog.close)
ui.button('撤销', on_click=dialog.close)
dialog.open()
ui.button('显示对话框', on_click=show_dialog)
# 定时器
def update_time():
time_label.set_text(f'当前时间: {datetime.now().strftime("%H:%M:%S")}')
time_label = ui.label()
ui.timer(1.0, update_time)
6. 第三方模块集成
6.1 与Pandas集成
NiceGui可以很好地与Pandas配合使用:
from nicegui import ui
import pandas as pd
import numpy as np
# 创建示例数据
df = pd.DataFrame({
'产品': ['A', 'B', 'C', 'D'],
'销量': np.random.randint(100, 1000, 4),
'利润': np.random.randint(50, 500, 4)
})
# 显示数据表格
ui.table({
'column_defs': [
{'headerName': col, 'field': col} for col in df.columns
],
'row_data': df.to_dict('records')
})
# 添加图表
ui.chart({
'title': {'text': '产品销量'},
'xAxis': {'categories': df['产品'].tolist()},
'series': [{
'name': '销量',
'data': df['销量'].tolist()
}]
})
ui.run()
6.2 与Matplotlib集成
from nicegui import ui
import matplotlib.pyplot as plt
import numpy as np
# 创建Matplotlib图形
fig, ax = plt.subplots()
x = np.linspace(0, 10, 100)
ax.plot(x, np.sin(x))
ax.set_title('正弦波')
# 在NiceGui中显示
ui.pyplot(fig).classes('w-full')
ui.run()
6.3 与OpenCV集成
from nicegui import ui
import cv2
import numpy as np
# 创建摄像头捕获组件
camera = ui.interactive_image()
def update_frame():
# 模拟从摄像头获取帧
frame = np.random.randint(0, 256, (480, 640, 3), dtype=np.uint8)
# 转换为Base64
_, img_encoded = cv2.imencode('.jpg', frame)
img_base64 = base64.b64encode(img_encoded).decode('utf-8')
# 更新图像
camera.set_source(f'data:image/jpeg;base64,{img_base64}')
# 每秒更新30帧
ui.timer(1/30, update_frame)
ui.run()
7. 部署与优化
7.1 部署为独立应用
from nicegui import ui
ui.label('我的独立应用')
ui.button('点击我')
# 设置标题和favicon
ui.run(title='我的应用', favicon='')
7.2 集成到现有Web服务
from nicegui import ui
from fastapi import FastAPI
import uvicorn
app = FastAPI()
@ui.page('/')
def main_page():
ui.label('集成到FastAPI的应用')
ui.run_with(app)
if __name__ == '__main__':
uvicorn.run(app)
7.3 优化提议
- 使用@ui.refreshable:只刷新必要的部分
- 合理使用定时器:避免过高频率的更新
- 减少大表数据:表格只加载可见数据
- 使用缓存:对计算结果进行缓存
- 异步操作:对耗时操作使用async/await
8. 常见问题
8.1 组件不更新怎么办?
确保使用响应式变量或调用refresh()方法:
# 错误方式
count = 0
def increment():
count += 1 # 界面不会更新
# 正确方式1
count = ui.state(0)
def increment():
count.value += 1 # 自动更新
# 正确方式2
count = 0
label = ui.label()
def increment():
global count
count += 1
label.set_text(f'计数: {count}') # 手动更新
8.2 如何自定义主题?
NiceGui支持Tailwind CSS,可以轻松自定义样式:
# 使用Tailwind类
ui.button('自定义按钮').classes('bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded')
# 或者直接使用CSS
ui.button('红色按钮').style('background-color: red; color: white;')
8.3 如何处理大型数据集?
对于大型数据集,提议:
- 使用分页加载
- 只加载可见数据
- 使用虚拟滚动
- 在服务器端处理数据
# 分页表格示例
table = ui.table({
'pagination': True,
'paginationPageSize': 10,
'columnDefs': [...],
'rowData': [...] # 只加载当前页数据
})
9. 总结
NiceGui是一个强劲而简单的Python Web界面库,特别适合:
- 快速原型开发
- 数据可视化应用
- 内部工具开发
- 教学演示
- 需要简单Web界面的Python脚本
它的主要优势在于:
- 开发速度快:几分钟就能创建功能完整的Web界面
- 学习成本低:只需Python知识
- 灵活性好:可以从小工具扩展到复杂应用
- 生态丰富:与Python数据科学生态无缝集成
通过本教程,我们可以掌握NiceGui的核心概念和实用技巧,目前可以开始构建自己的Web应用了!
提示:NiceGUI还在不断发展中,案例中的代码需要根据您使用的NiceGUI版本进行响应的修改。
10. 资源与延伸阅读
- NiceGui官方文档:(https://nicegui.io/documentation)
- NiceGitHub仓库:(https://github.com/zauberzeug/nicegui)
- Tailwind CSS参考:(https://tailwindcss.com/docs)
- Pandas文档:(https://pandas.pydata.org/docs/)
- Matplotlib示例:(https://matplotlib.org/stable/gallery/index.html)
#编程# #学习# #python# #在头条记录我的2025#







有本地文件选择界面吗?
文件对话框组件
flet不是更好,多端?
非常好
多页面应用好维护吗?
组件自动更新很方便👏
收藏了,感谢分享