Python Web应用开发:NiceGUI控制组件详解

NiceGUI基于Quasar框架和Vue.js,允许开发者使用纯Python代码创建交互式Web界面,无需深入学习HTML、CSS和JavaScript。其核心优势在于:

  • 简洁的Python API,降低开发门槛
  • 丰富的预构建组件,覆盖大部分UI需求
  • 自动处理前端与后端的通信
  • 支持实时更新和响应式设计

NiceGUI作为一款基于Python的现代化UI框架,为开发者提供了简洁直观的API,能够快速构建出美观且功能丰富的Web界面。

1. 环境准备

在开始学习之前,需要准备以下开发环境:

  • Python 3.13.0
  • NiceGUI 2.20.0+

安装NiceGUI的命令:

pip install nicegui>=2.20.0

验证安装:

from nicegui import ui

ui.label('Hello, NiceGUI!')
ui.run()

运行上述代码后,会自动启动一个Web服务器并在默认浏览器中打开页面,显示'Hello, NiceGUI!'即表示环境搭建成功。

2. 按钮组件

按钮是Web界面中最基础也最常用的交互组件,用于触发各种操作。NiceGUI提供了多种类型的按钮组件,以满足不同的交互需求。

2.1 基础按钮(Button)

基础按钮是最常用的按钮类型,用于触发单击事件。

2.1.1 定义与原理

Button组件基于Quasar的QBtn组件实现,支持多种颜色设置和图标显示,能够响应用户的点击事件。

2.1.2 语法与参数

ui.button(text, on_click=None, color='primary', icon=None)

参数

说明

text

按钮的标签文本

on_click

按钮被点击时的回调函数

color

按钮颜色(可以是Quasar、TailWind或者CSS颜色,默认值:'primary')

icon

显示在按钮上的图标名称(默认值:None)

注意:存在像'red'这种同时属于Quasar颜色和CSS颜色的名称,此时将优先使用Quasar颜色。

2.1.3 示例代码

from nicegui import ui

# 基础按钮
ui.button('点击我', on_click=lambda: ui.notify('按钮被点击了!'))

# 带图标的按钮
ui.button('保存', icon='save', on_click=lambda: ui.notify('保存成功'))

# 不同颜色的按钮
with ui.row():
    ui.button('主要', color='primary')
    ui.button('成功', color='success')
    ui.button('警告', color='warning')
    ui.button('危险', color='error')

ui.run()

效果:

2.1.4 要点与技巧

  • 回调函数可以是任何可调用对象,包括lambda表达式、函数等
  • 可以通过props()方法添加额外的属性,如ui.button('方形按钮').props('square')
  • 使用classes()方法可以添加CSS类来自定义样式

2.2 按钮组(Button Group)

按钮组用于将多个相关按钮组合在一起,形成一个逻辑单元。

2.2.1 定义与原理

Button Group基于Quasar的QBtnGroup组件,用于将多个按钮组织在一起,共享相同的样式和行为。

2.2.2 语法与使用

使用with ui.button_group():上下文管理器来创建按钮组,在其中添加的按钮会自动成为组的一部分。

2.2.3 示例代码

from nicegui import ui with ui.button_group(): ui.button('新建', icon='add', on_click=lambda: ui.notify('新建文档')) ui.button('打开', icon='folder_open', on_click=lambda: ui.notify('打开文档')) ui.button('保存', icon='save', on_click=lambda: ui.notify('保存文档')) # 带选中状态的按钮组 with ui.button_group(): ui.button('左对齐', icon='format_align_left').props('toggle') ui.button('居中对齐', icon='format_align_center').props('toggle') ui.button('右对齐', icon='format_align_right').props('toggle') ui.run()

效果:


2.2.4 注意事项

  • 按钮组中的按钮应使用相同的props设计,以保持视觉一致性
  • 使用toggle属性可以创建具有选中状态的按钮组
  • 按钮组会自动处理按钮之间的间距和边框

2.3 下拉按钮(Dropdown Button)

下拉按钮在点击时会显示一个下拉菜单,包含多个可选择的选项。

2.3.1 定义与原理

Dropdown Button基于Quasar的QBtnDropDown组件,结合了按钮和下拉菜单的功能,适合展示一组相关的操作选项。

2.3.2 语法与参数

ui.dropdown_button(text, value=False, on_value_change=None, on_click=None, color='primary')

参数

说明

text

按钮的标签文本

value

下拉菜单是否被打开(默认值:False)

on_value_change

在下拉菜单被打开或关闭时的回调函数

on_click

按钮被点击时的回调函数

color

按钮颜色(默认值:'primary')

2.3.3 示例代码

from nicegui import ui with ui.dropdown_button('文件操作', auto_close=True): ui.item('新建', on_click=lambda: ui.notify('新建文件')) ui.item('打开', on_click=lambda: ui.notify('打开文件')) ui.separator() # 添加分隔线 ui.item('保存', on_click=lambda: ui.notify('保存文件')) ui.item('另存为', on_click=lambda: ui.notify('文件另存为')) # 带图标的下拉按钮 with ui.dropdown_button('编辑', icon='edit'): ui.item('复制', on_click=lambda: ui.notify('复制')) ui.item('剪切', on_click=lambda: ui.notify('剪切')) ui.item('粘贴', on_click=lambda: ui.notify('粘贴')) ui.run()

效果:

2.3.4 要点与技巧

  • 使用auto_close=True可以设置选择菜单项后自动关闭下拉菜单
  • 可以使用ui.separator()添加分隔线,对菜单项进行分组
  • 菜单项可以包含图标,提高可读性

2.4 浮动按钮(FAB)

浮动按钮(Floating Action Button)是一种特殊的按钮,通常位于界面的角落,点击后可以展开多个功能按钮。

2.4.1 定义与原理

FAB基于Quasar的QFab组件,是一种悬浮在界面上的按钮,点击后可以展开多个相关的操作按钮,适合放置常用的核心功能。

2.4.2 语法与参数

ui.fab(icon, label=None, value=False, color='primary', direction='right')

参数

说明

icon

在FAB上显示的图标

label

FAB的可选标签

value

FAB 是否已打开(默认:False)

color

FAB的背景颜色(默认:primary)

direction

FAB展开的方向('up'、'down'、'left'、'right',默认:'right')

2.4.3 示例代码

from nicegui import ui # 基础FAB示例 with ui.fab('add', label='操作'): ui.fab_action('person_add', on_click=lambda: ui.notify('添加用户')) ui.fab_action('file_add', on_click=lambda: ui.notify('添加文件')) ui.fab_action('note_add', on_click=lambda: ui.notify('添加笔记')) # 不同方向的FAB with ui.row().classes('absolute bottom-4 left-4'): with ui.fab('menu', direction='up', color='secondary'): ui.fab_action('settings') ui.fab_action('help') with ui.fab('share', direction='down', color='green'): ui.fab_action('email') ui.fab_action('message') ui.fab_action('publish') ui.run()

效果:

2.4.4 应用场景

  • 用于放置应用的核心功能入口
  • 适合在移动设备上提供便捷操作
  • 可以通过absolute类将其固定在屏幕的某个位置

3. 标签与指示器

标签和指示器用于展示简短信息或状态,增强界面的可读性和交互性。

3.1 标签(Badge)

标签用于展示简短的附加信息,如通知数量、状态标识等。

3.1.1 定义与原理

Badge基于Quasar的QBadge组件,用于显示简短的提示信息,通常附加在其他组件旁边。

3.1.2 语法与参数

ui.badge(text, color='primary', text_color=None, outline=False)

参数

说明

text

标签的文本内容

color

标签的背景颜色(默认值:'primary')

text_color

文本颜色(默认值:None)

outline

使用外框设计(默认值:False)

3.1.3 示例代码

from nicegui import ui # 基础标签 ui.badge('新消息') ui.badge('99+', color='red') ui.badge('推荐', color='green', outline=True) # 与按钮结合使用 with ui.button('通知'): ui.badge('5', color='red').props('floating') # 动态更新标签 count = 0 def increment(): nonlocal count count += 1 badge.set_text(str(count)) ui.button('点击计数', on_click=increment) badge = ui.badge('0', color='blue') ui.run()

效果:

3.1.4 应用场景

  • 显示未读消息数量
  • 标识项目状态(如新、热门、推荐等)
  • 作为计数器显示操作次数

3.2 小标签(Chip)

小标签是一种更灵活的标签组件,可以被点击、选择或移除。

3.2.1 定义与原理

Chip基于Quasar的QChip组件,比Badge更灵活,支持交互功能,如点击、选择和移除。

3.2.2 语法与参数

ui.chip(text='', icon=None, color='primary', text_color=None, 
        on_click=None, selectable=False, selected=False, 
        on_selection_change=None, removable=False, on_value_change=None)

参数

说明

text

文本的初始值(默认值:'')

icon

显示在标签上的图标名(默认值:None)

color

标签的背景色(默认值:'primary')

text_color

标签的文本颜色(默认值:None)

on_click

标签被点击时的回调函数

selectable

该标签是否可被选中(默认值:False)

selected

该标签是否被选中(默认值:False)

on_selection_change

标签选中状态改变的回调函数

removable

此标签是否可被移除(默认值:False)

on_value_change

标签被移除或未被移除时调用的回调函数

3.2.3 示例代码

from nicegui import ui with ui.row().classes('gap-2'): # 可点击的标签 ui.chip('点击我', icon='hand_point_up', on_click=lambda: ui.notify('标签被点击了')) # 可选择的标签 ui.chip('可选择', icon='check', selectable=True, on_selection_change=lambda e: ui.notify(f'选中状态: {e.value}')) # 可移除的标签 ui.chip('可移除', icon='delete', removable=True, on_value_change=lambda e: ui.notify(f'标签被移除: {not e.value}')) # 自定义样式的标签 ui.chip('自定义样式', icon='star', color='yellow-4').props('outline square') # 禁用的标签 ui.chip('已禁用', icon='block', color='grey').set_enabled(False) # 动态标签示例 tags = ['Python', 'NiceGUI', 'Web开发'] tag_chips = [] def add_tag(): tag = input_field.value if tag and tag not in [c.text for c in tag_chips]: chip = ui.chip(tag, removable=True, on_value_change=lambda e, c=chip: remove_tag(c)) tag_chips.append(chip) input_field.set_value('') ui.update() def remove_tag(chip): if chip in tag_chips: tag_chips.remove(chip) chip.delete() input_field = ui.input(placeholder='输入标签...') ui.button('添加', on_click=add_tag) ui.run()

效果:

3.2.4 应用场景

  • 显示标签集合(如文章标签)
  • 作为过滤器选项
  • 展示可移除的选择项
  • 用于标签编辑功能

4. 选择组件

选择组件用于从多个选项中选取一个或多个值,是表单中常用的交互元素。

4.1 切换器(Toggle)

切换器允许用户在多个选项中选择一个,通常以按钮组的形式展示。

4.1.1 定义与原理

Toggle基于Quasar的QBtnToggle组件,提供了一种直观的方式让用户在多个选项中进行单选。

4.1.2 语法与参数

ui.toggle(options, value=None, on_change=None, clearable=False)

参数

说明

options

选项列表(列表['value1', ...]或字典{'value1':'label1', ...})

value

初始选中的值

on_change

当选中项改变时的回调函数

clearable

选中状态是否可移除(默认值:False)

4.1.3 示例代码

from nicegui import ui # 基础切换器 toggle1 = ui.toggle([1, 2, 3], value=1, on_change=lambda e: ui.notify(f'选中: {e.value}')) # 使用字典定义选项(值:标签) toggle2 = ui.toggle({'small': '小', 'medium': '中', 'large': '大'}, value='medium') # 可清除的切换器 toggle3 = ui.toggle(['红', '绿', '蓝'], clearable=True) # 绑定两个切换器的值 toggle_a = ui.toggle([10, 20, 30], value=20) toggle_b = ui.toggle({10: '十', 20: '二十', 30: '三十'}).bind_value(toggle_a, 'value') ui.run()

效果:

4.1.4 要点与技巧

  • 选项可以是简单列表或键值对字典
  • 使用bind_value方法可以实现多个组件的值同步
  • 当clearable=True时,点击已选中的选项可以取消选择

4.2 单项选择器(Radio Selection)

单选按钮允许用户从多个选项中选择一个,以圆形单选框的形式展示。

4.2.1 定义与原理

Radio基于Quasar的QRadio组件,是一种经典的单选控件,每个选项都有一个圆形单选框。

4.2.2 语法与参数

ui.radio(options, value=None, on_change=None)

参数

说明

options

选项列表(列表['value1', ...]或字典{'value1':'label1', ...})

value

初始选中的值

on_change

当选中项改变时的回调函数

4.2.3 示例代码

from nicegui import ui # 垂直排列的单选按钮 ui.radio(['苹果', '香蕉', '橙子'], value='香蕉', on_change=lambda e: ui.notify(f'选中了: {e.value}')) # 水平排列的单选按钮 ui.radio({'male': '男', 'female': '女', 'other': '其他'}, value='male').props('inline') # 绑定两个单选组件 radio1 = ui.radio([1, 2, 3], value=2) radio2 = ui.radio({1: '一', 2: '二', 3: '三'}).props('inline').bind_value(radio1, 'value') ui.run()

效果:

4.2.4 注意事项

  • 使用props('inline')可以将选项水平排列
  • 与toggle相比,radio更适合在表单中使用,视觉上更明确
  • 选项变更时会触发on_change回调,并传递包含新值的事件对象

4.3 下拉选择器(Dropdown Selection)

下拉选择器在点击时展开一个下拉菜单,允许用户从中选择一个或多个选项。

4.3.1 定义与原理

Dropdown Selection基于Quasar的QSelect组件,是一种节省空间的选择控件,特别适合选项较多的情况。

4.3.2 语法与参数

ui.select(options, label=None, value=None, on_change=None, with_input=False,
          new_value_mode=None, multiple=False, clearable=False, validation=None,
          key_generator=None)

参数

说明

options

选项列表或字典

label

选择器的标题

value

初始选中的值

on_change

当选中项改变时的回调函数

with_input

是否显示用于筛选选项的输入框

new_value_mode

是否接受用户输入新的值(默认值:None,代表不接受)

multiple

是否允许多选

clearable

是否添加清除选择的按钮

validation

验证规则字典或返回错误信息的可调用对象

key_generator

为新增值生成字典键的回调函数或迭代器

4.3.3 示例代码

from nicegui import ui # 基础下拉选择器 ui.select(['Python', 'Java', 'JavaScript'], label='编程语言', on_change=lambda e: ui.notify(f'选择了: {e.value}')) # 带标签和初始值的选择器 ui.select({'1': '周一', '2': '周二', '3': '周三', '4': '周四', '5': '周五'}, label='工作日', value='3') # 可搜索的选择器 ui.select(['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry', 'Fig', 'Grape'], label='水果', with_input=True) # 支持多选的选择器 ui.select(['红色', '绿色', '蓝色', '黄色', '紫色'], label='颜色', multiple=True, clearable=True) # 支持输入新值的选择器 ui.select(['北京', '上海', '广州', '深圳'], label='城市', new_value_mode='add', on_change=lambda e: ui.notify(f'选择了: {e.value}')) ui.run()

效果:

4.3.4 要点与技巧

  • 使用with_input=True可以启用搜索功能,方便在大量选项中查找
  • multiple=True启用多选模式,此时value将是一个列表
  • new_value_mode参数控制如何处理用户输入的新值,可选值包括'add'、'toggle'等
  • 验证规则可以用于限制输入,如validation={'请选择至少一个': lambda v: v is not None}

4.4 Input Chips

Input Chips允许用户以芯片(标签)形式输入和管理多个值。

4.4.1 定义与原理

Input Chips基于Quasar的QSelect组件,专注于支持自由文本输入的芯片功能,适合用于标签、关键词等场景。

4.4.2 语法与参数

ui.input_chips(label=None, value=None, on_change=None, new_value_mode='toggle',
               clearable=False, validation=None)

参数

说明

label

选择框上方显示的标签文本

value

初始选中的值

on_change

当选择发生变化时执行的回调函数

new_value_mode

处理用户输入新值的方式(默认值:'toggle')

clearable

是否显示清除选择的按钮

validation

验证规则字典或返回错误信息的可调用对象

4.4.3 示例代码

from nicegui import ui # 基础芯片输入器 ui.input_chips('爱好', value=['阅读', '运动', '音乐']) # 带验证的芯片输入器 def validate_tag(value): if len(value) < 2: return '标签长度不能小于2' if len(value) > 10: return '标签长度不能大于10' return None ui.input_chips('关键词', validation=validate_tag) # 监听变化的芯片输入器 def handle_changes(e): tag_list.set_text(f'当前标签: {', '.join(e.value)}') chips = ui.input_chips('动态标签', on_change=handle_changes) tag_list = ui.label() ui.run()

效果:

4.4.4 应用场景

  • 标签输入(如文章标签)
  • 关键词集合
  • 多值筛选条件
  • 收件人列表

5. 布尔值组件

布尔值组件用于表示和控制真/假状态,包括复选框、开关等。

5.1 复选框(Checkbox)

复选框允许用户选择或取消选择一个选项,通常用于表示布尔值状态。

5.1.1 定义与原理

Checkbox基于Quasar的QCheckBox组件,是一种经典的布尔值选择控件,以方框形式展示,选中时会显示勾选标记。

5.1.2 语法与参数

ui.checkbox(text, value=False, on_change=None)

参数

说明

text

显示在复选框边上的文字

value

是否默认被选中(默认值:False)

on_change

当选中状态改变时的回调函数

5.1.3 示例代码

from nicegui import ui # 基础复选框 ui.checkbox('我已阅读并同意条款', on_change=lambda e: ui.notify(f'同意: {e.value}')) # 绑定其他组件的可见性 agree = ui.checkbox('显示详细信息') details = ui.label('这些是详细信息...').bind_visibility_from(agree, 'value') # 复选框组 hobbies = [] def update_hobbies(爱好, 选中): if 选中 and 爱好 not in hobbies: hobbies.append(爱好) elif not 选中 and 爱好 in hobbies: hobbies.remove(爱好) hobby_list.set_text(f'选中的爱好: {', '.join(hobbies)}') ui.checkbox('阅读', on_change=lambda e: update_hobbies('阅读', e.value)) ui.checkbox('运动', on_change=lambda e: update_hobbies('运动', e.value)) ui.checkbox('音乐', on_change=lambda e: update_hobbies('音乐', e.value)) hobby_list = ui.label() ui.run()

效果:

5.1.4 应用场景

  • 同意条款或条件
  • 启用/禁用某个功能
  • 多选列表中的项目选择
  • 控制其他元素的可见性或状态

5.2 开关(Switch)

开关是一种视觉上更现代的布尔值控制组件,模拟物理开关的外观和行为。

5.2.1 定义与原理

Switch基于Quasar的QToggle组件,提供了一种类似物理开关的交互方式,比复选框更具视觉吸引力。

5.2.2 语法与参数

ui.switch(text, value=False, on_change=None)

参数

说明

text

显示在开关边上的文字

value

是否默认被打开(默认值:False)

on_change

当开启状态改变时的回调函数

5.2.3 示例代码

from nicegui import ui # 基础开关 ui.switch( '启用通知', on_change=lambda e: ui.notify(f'通知已{'开启' if e.value else '关闭'}') ) # 绑定到其他组件 dark_mode = ui.switch('深色模式') # 开关组 with ui.column(): ui.switch('自动保存', value=True) ui.switch('允许推送', value=False) ui.switch('记住登录状态', value=True) ui.switch('高级模式', value=False) ui.run()

效果:

5.2.4 注意事项

  • 开关更适合表示'启用/禁用'类型的选项
  • 与复选框相比,开关的视觉反馈更强烈
  • 可以通过bind_classes_from等方法将开关状态与其他组件的样式绑定

6. 数值输入组件

数值输入组件用于获取用户输入的数值,包括滑块、范围选择器、旋钮等。

6.1 滑块(Slider)

滑块允许用户通过拖动来选择一个数值,提供直观的数值输入方式。

6.1.1 定义与原理

Slider基于Quasar的QSlider组件,通过拖动滑块来选择一个在指定范围内的数值,适合需要直观调整数值的场景。

6.1.2 语法与参数

ui.slider(min=0, max=100, step=1, value=None, on_change=None)

参数

说明

min

滑块的最小值

max

滑块的最大值

step

滑块的步进值

value

滑块的初始值

on_change

当滑块的值被改变时的回调函数

6.1.3 示例代码

from nicegui import ui # 基础滑块 slider1 = ui.slider(min=0, max=100, value=50) ui.label().bind_text_from(slider1, 'value', backward=lambda v: f'值: {v}') # 不同范围和步长的滑块 slider2 = ui.slider(min=0, max=1, step=0.01, value=0.5) ui.label().bind_text_from(slider2, 'value', backward=lambda v: f'比例: {v:.2f}') ui.run()

6.1.4 应用场景

  • 音量控制
  • 亮度调节
  • 字体大小调整
  • 过滤条件中的数值范围选择

6.2 范围选择器(Range)

范围选择器允许用户选择一个数值范围,通过两个滑块来定义最小值和最大值。

6.2.1 定义与原理

Range基于Quasar的QRange组件,提供了两个滑块来选择一个数值范围,适合需要设置上下限的场景。

6.2.2 语法与参数

ui.range(min=0, max=100, step=1, value=None, on_change=None)

参数

说明

min

选择器的最小值

max

选择器的最大值

step

选择器的步进值

value

选择器的初始值(字典形式:{'min': ..., 'max': ...})

on_change

当选择器的值被改变时的回调函数

6.2.3 示例代码

from nicegui import ui # 基础范围选择器 range1 = ui.range(min=0, max=100, value={'min': 20, 'max': 80}) ui.label().bind_text_from(range1, 'value', backward=lambda v: f'范围: {v['min']} - {v['max']}') # 价格范围选择器 range2 = ui.range(min=0, max=1000, step=10, value={'min': 200, 'max': 800}) ui.label().bind_text_from(range2, 'value', backward=lambda v: f'价格范围: ¥{v['min']} - ¥{v['max']}') # 应用范围选择器 - 过滤数据 data = list(range(1, 101)) # 模拟数据 range_filter = ui.range(min=1, max=100, value={'min': 10, 'max': 90}) result_label = ui.label() def update_filter(e): filtered = [x for x in data if e.value['min'] <= x <= e.value['max']] result_label.set_text(f'筛选结果: {len(filtered)} 项数据') range_filter.on('change', update_filter) update_filter(range_filter) # 初始更新 ui.run()

6.2.4 应用场景

  • 价格区间筛选
  • 时间范围选择
  • 数据过滤条件设置
  • 数值区间限定

6.3 评分组件(Rating)

评分组件允许用户通过选择星级来输入评分值,通常用于评价系统。

6.3.1 定义与原理

Rating基于Quasar的QRating组件,提供了一种直观的评分输入方式,用户可以通过点击星级来设置评分值。

6.3.2 语法与参数

ui.rating(value=None, max=5, icon='star', icon_selected=None, icon_half=None,
          color='primary', size=None, on_change=None)

参数

说明

value

初始值(默认值:None)

max

最大分值(默认值:5)

icon

分值图标的名称(默认值:'star')

icon_selected

选中的值的图标(默认跟随icon)

icon_half

当选中半分的时候的图标(默认跟随icon)

color

图标的颜色(默认值:'primary')

size

CSS单元尺寸,如'16px'或'lg'

on_change

当评分的值被改变时的回调函数

6.3.3 示例代码

from nicegui import ui # 基础评分组件 rating1 = ui.rating(value=3) ui.label().bind_text_from(rating1, 'value', backward=lambda v: f'评分: {v} 星') # 自定义评分组件 ui.rating( value=4.5, max=10, icon='favorite', color='red', on_change=lambda e: ui.notify(f'评分: {e.value} 分') ) # 只读评分展示 ui.label('用户评分:') ui.rating(value=4.2, max=5).props('readonly') ui.run()

效果:

6.3.4 应用场景

  • 产品评价系统
  • 内容评分
  • 满意度调查
  • 星级展示

6.4 旋钮(Knob)

旋钮是一种圆形的数值输入组件,用户可以通过旋转来调整数值。

6.4.1 定义与原理

Knob基于Quasar的QKnob组件,提供了一种直观的圆形数值输入方式,适合需要精确调整数值的场景。

6.4.2 语法与参数

ui.knob(value=0.0, min=0.0, max=1.0, step=0.01, color='primary', 
        center_color=None, track_color=None, size=None, show_value=False,
        on_change=None)

参数

说明

value

初始值(默认值:0.0)

min

最小值(默认值:0.0)

max

最大值(默认值:1.0)

step

步进值(默认值:0.01)

color

轨迹的颜色(默认值:'primary')

center_color

组件中心的颜色

track_color

轨道的颜色

size

CSS单元尺寸

show_value

是否显示旋钮的值(默认值:False)

on_change

当旋钮的值被改变时的回调函数

6.4.3 示例代码

from nicegui import ui # 基础旋钮 knob1 = ui.knob(0.3, show_value=True) ui.label().bind_text_from(knob1, 'value', backward=lambda v: f'值: {v:.2f}') # 自定义样式的旋钮 with ui.row().classes('gap-4'): ui.knob(50, min=0, max=100, step=1, color='red', show_value=True) ui.knob(0.5, min=0, max=1, color='green', track_color='grey-2', show_value=True) # 绑定到其他组件 - 音量控制 volume_knob = ui.knob(70, min=0, max=100, step=1, color='blue', show_value=True) with ui.knob(color='orange', track_color='grey-2').bind_value(volume_knob, 'value'): ui.icon('volume_up') ui.run()

效果:

6.4.4 应用场景

  • 音量控制
  • 亮度调节
  • 速度控制
  • 任何需要精确数值调整的场景

7. 输入组件

输入组件用于收集用户的文本、数字、颜色等输入信息,是表单的核心组成部分。

7.1 单行文本输入(Text Input)

单行文本输入框用于收集用户的单行文本输入,如用户名、邮箱等。

7.1.1 定义与原理

Text Input基于Quasar的QInput组件,提供了单行文本输入功能,支持输入验证、自动完成等特性。

7.1.2 语法与参数

ui.input(label=None, placeholder=None, value=None, password=False,
         password_toggle_button=False, on_change=None, autocomplete=None,
         validation=None)

参数

说明

label

输入框的标题

placeholder

当输入框为空时显示的文字提示

value

输入框的初始值

password

是否需要隐藏输入内容(默认值:False)

password_toggle_button

是否显示密码切换按钮(默认值:False)

on_change

当输入框的内容被改变时的回调函数

autocomplete

用于自动完成的列表

validation

验证规则字典或返回错误信息的可调用对象

7.1.3 示例代码

from nicegui import ui # 基础文本输入 ui.input(label='姓名', placeholder='请输入您的姓名') # 带密码功能的输入 ui.input(label='密码', password=True, password_toggle_button=True) # 带验证的输入 ui.input( label='邮箱', placeholder='请输入邮箱地址', validation={ '请输入邮箱': lambda v: v, '请输入有效的邮箱': lambda v: '@' in v } ) # 带自动完成的输入 ui.input( label='编程语言', placeholder='输入编程语言', autocomplete=['Python', 'Java', 'JavaScript', 'C++', 'C#', 'Ruby', 'Go'] ) # 实时响应的输入 input_field = ui.input(label='实时显示', placeholder='输入内容...') output_label = ui.label().bind_text_from(input_field, 'value', backward=lambda v: f'您输入了: {v}') ui.run()

7.1.4 要点与技巧

  • 每次按键都会触发on_change事件,如果希望在用户确认输入后才响应,可以监听keydown.enter或blur事件
  • 验证规则可以是一个字典,键为错误提示信息,值为验证函数
  • 使用password=True可以创建密码输入框,配合password_toggle_button=True允许用户切换密码可见性

7.2 多行文本输入(Textarea)

多行文本输入框用于收集用户的多行文本输入,如评论、描述等。

7.2.1 定义与原理

Textarea基于Quasar的QInput组件,专门设计用于多行文本输入,支持自动换行和输入验证。

7.2.2 语法与参数

ui.textarea(label=None, placeholder=None, value=None, on_change=None, validation=None)

参数

说明

label

输入框的标题

placeholder

当输入框为空时显示的文字提示

value

输入框的初始值

on_change

当输入框的内容被改变时的回调函数

validation

验证规则字典或返回错误信息的可调用对象

7.2.3 示例代码

from nicegui import ui # 基础多行文本输入 ui.textarea(label='评论', placeholder='请输入您的评论...').classes('h-32') # 带初始值的文本区域 initial_text = '''这是一段初始文本 它包含多行内容 用于演示多行文本输入框 ''' ui.textarea(label='多行编辑', value=initial_text).classes('h-40') # 带验证的文本区域 ui.textarea( label='描述', placeholder='请输入描述(至少10个字符)', validation={'描述太短': lambda v: len(v) >= 10} ).classes('h-24') # 实时统计字符数 textarea = ui.textarea(label='文章内容', placeholder='请输入文章内容...').classes('h-32') char_count = ui.label().bind_text_from( textarea, 'value', backward=lambda v: f'字符数: {len(v)}' ) ui.run()

7.2.4 注意事项

  • 使用classes('h-32')等方式可以设置文本区域的高度
  • 文本区域会自动处理换行符
  • 适合输入较长的文本内容,如评论、描述、文章等

7.3 代码编辑器(CodeMirror)

代码编辑器提供了语法高亮、代码折叠等功能,专门用于代码输入和编辑。

7.3.1 定义与原理

CodeMirror基于CodeMirror库,提供了功能丰富的代码编辑环境,支持多种编程语言的语法高亮和编辑功能。

7.3.2 语法与参数

ui.codemirror(value='', on_change=None, language=None, theme='basicLight',
              indent='  ', line_wrapping=False, highlight_whitespace=False)

参数

说明

value

编辑器的初始值

on_change

当编辑器中的内容被改变时的回调函数

language

编辑器的初始语言(不区分大小写,默认值:None)

theme

编辑器的初始主题(默认值:'basicLight')

indent

用于缩进的字符串(默认值:' ')

line_wrapping

是否自动换行(默认值:False)

highlight_whitespace

是否高亮空白字符(默认值:False)

7.3.3 示例代码

from nicegui import ui # 基础代码编辑器 ui.codemirror('print('Hello, World!')', language='Python').classes('h-40') # 可切换语言和主题的编辑器 editor = ui.codemirror( 'function hello() {n console.log('Hello, World!');n}', language='JavaScript', theme='githubDark' ).classes('h-64') with ui.row().classes('gap-4'): ui.select(editor.supported_languages, label='语言', clearable=True) .classes('w-40').bind_value(editor, 'language') ui.select(editor.supported_themes, label='主题') .classes('w-40').bind_value(editor, 'theme') # 带实时预览的Markdown编辑器 md_editor = ui.codemirror('# 标题nn这是一段Markdown文本', language='Markdown').classes('h-40') preview = ui.markdown().bind_content_from(md_editor, 'value') ui.run()

效果:

7.3.4 支持的语言与主题

CodeMirror支持超过140种编程语言和30余种主题,常见的包括:

  • 语言:Python、JavaScript、HTML、CSS、Java、C++、Markdown等
  • 主题:githubLight、githubDark、monokai、vscodeLight、vscodeDark等

可以通过editor.supported_languages和editor.supported_themes查看所有支持的语言和主题。

7.4 数字输入器(Number Input)

数字输入器专门用于收集数值输入,提供了数值验证和步进控制。

7.4.1 定义与原理

Number Input基于Quasar的QInput组件,专门用于处理数值输入,支持范围限制、精度控制和格式化显示。

7.4.2 语法与参数

ui.number(label=None, placeholder=None, value=None, min=None, max=None,
          precision=None, step=None, prefix=None, suffix=None, format=None,
          on_change=None, validation=None)

参数

说明

label

数字输入框的标题

placeholder

当输入框为空时显示的文字提示

value

输入框的初始值

min

允许的最小值

max

允许的最大值

precision

允许的小数位数(默认: 无限制)

step

步进按钮的步长

prefix

显示值前添加的前缀

suffix

显示值后添加的后缀

format

格式化显示值的字符串,如%.2f

on_change

当输入框中的内容被改变时的回调函数

validation

验证规则字典或返回错误信息的可调用对象

7.4.3 示例代码

from nicegui import ui # 基础数字输入 ui.number(label='年龄', value=25, min=0, max=120) # 带格式化的数字输入 ui.number(label='体重', value=65.5, format='%.1f kg', step=0.1) # 带前缀和步进的数字输入 ui.number(label='价格', value=99.99, prefix='¥', step=10, min=0) # 百分比输入 ui.number(label='折扣', value=80, suffix='%', min=0, max=100, step=5) # 带验证的数字输入 ui.number( label='数量', value=1, min=1, max=100, validation={'数量必须是5的倍数': lambda v: v % 5 == 0} ) # 显示数值变化 number_input = ui.number(label='数值', value=0, min=-100, max=100) ui.label().bind_text_from(number_input, 'value', backward=lambda v: f'当前值: {v}') ui.run()

7.4.4 应用场景

  • 年龄、体重等个人信息输入
  • 价格、数量等商业数据输入
  • 百分比、折扣等比例数据输入
  • 需要数值验证的表单字段

7.5 颜色输入器(Color Input)

颜色输入器允许用户选择颜色,以RGB色号的形式返回。

7.5.1 定义与原理

Color Input基于Quasar的QInput组件,提供了颜色选择功能,用户可以直接输入色号或通过颜色选择器选择颜色。

7.5.2 语法与参数

ui.color_input(label=None, placeholder=None, value=None, on_change=None, preview=False)

参数

说明

label

RGB色号输入框的标题

placeholder

当输入框为空时显示的文字提示

value

输入框的初始值

on_change

当输入框中的色号被改变时的回调函数

preview

将选择的颜色应用到按钮背景(默认值:False)

7.5.3 示例代码

from nicegui import ui # 基础颜色输入 color_input1 = ui.color_input(label='颜色选择', value='#ff0000') ui.label().bind_text_from(color_input1, 'value', backward=lambda v: f'当前颜色: {v}') # 带预览的颜色输入 color_input2 = ui.color_input(label='带预览', value='#00ff00', preview=True) # 实时应用颜色 text_label = ui.label('这段文字的颜色会跟随选择变化') ui.color_input( label='文本颜色', value='#0000ff', on_change=lambda e: text_label.style(f'color: {e.value}') ) # 颜色应用示例 with ui.card().classes('p-4') as card: ui.label('这个卡片的背景色会变化') ui.color_input( label='卡片背景色', value='#f0f0f0', on_change=lambda e: card.style(f'background-color: {e.value}') ) ui.run()

7.5.4 应用场景

  • 主题颜色设置
  • 自定义元素颜色
  • 图形编辑工具
  • 数据可视化颜色配置

7.6 颜色选择器(Color Picker)

颜色选择器提供了一个可视化的界面,让用户可以更直观地选择颜色。

7.6.1 定义与原理

Color Picker基于Quasar的QMenu和QColor组件,提供了一个弹出式的颜色选择界面,支持通过调色板、色轮等方式选择颜色。

7.6.2 语法与参数

ui.color_picker(on_pick=None, value=False)

参数

说明

on_pick

当选择了一个色号执行的回调函数

value

选择器是否打开(默认值:False)

7.6.3 示例代码

from nicegui import ui # 基础颜色选择器 with ui.button('选择颜色') as button: ui.color_picker(on_pick=lambda e: button.style(f'background-color: {e.color}')) # 应用颜色到文本 text_label = ui.label('这段文字的颜色会变化') with ui.button('更改文本颜色'): ui.color_picker(on_pick=lambda e: text_label.style(f'color: {e.color}')) # 颜色选择器与输入框结合 color_value = '#000000' color_input = ui.input(label='颜色值', value=color_value) def update_color(e): global color_value color_value = e.color color_input.set_value(color_value) color_preview.style(f'background-color: {color_value}') with ui.button('选择颜色'): ui.color_picker(on_pick=update_color) color_preview = ui.element('div').classes('w-8 h-8 mt-2 border rounded') color_preview.style(f'background-color: {color_value}') ui.run()

7.6.4 注意事项

  • 颜色选择器通常与按钮结合使用,点击按钮弹出选择器
  • 选择颜色后,回调函数会收到包含color属性的事件对象
  • 可以与颜色输入框结合使用,提供更灵活的颜色输入方式

8. 日期和时间组件

日期和时间组件用于收集用户输入的日期和时间信息,提供了直观的选择界面。

8.1 日期选择器(Date Input)

日期选择器允许用户选择一个或多个日期,或一个日期范围。

8.1.1 定义与原理

Date Input基于Quasar的QDate组件,提供了日历式的日期选择界面,支持选择单个日期、多个日期或日期范围。

8.1.2 语法与参数

ui.date(value=None, mask='YYYY-MM-DD', on_change=None)

参数

说明

value

初始日期

mask

日期的格式(默认值:'YYYY-MM-DD')

on_change

当选择了一个日期执行的回调函数

8.1.3 示例代码

from nicegui import ui # 选择单个日期 ui.date(value='2023-10-01', on_change=lambda e: result1.set_text(f'选择的日期: {e.value}')) result1 = ui.label() # 选择日期范围 ui.date({'from': '2023-01-01', 'to': '2023-01-05'}, on_change=lambda e: result2.set_text(f'选择的范围: {e.value}')).props('range') result2 = ui.label() # 选择多个日期 ui.date(['2023-01-01', '2023-01-02', '2023-01-03'], on_change=lambda e: result3.set_text(f'选择的多个日期: {e.value}')).props('multiple') result3 = ui.label() # 自定义日期格式 ui.date(value='10/01/2023', mask='MM/DD/YYYY', on_change=lambda e: result4.set_text(f'选择的日期: {e.value}')) result4 = ui.label() ui.run()

8.1.4 要点与技巧

  • 使用props('range')启用日期范围选择模式
  • 使用props('multiple')启用多日期选择模式
  • 日期格式通过mask参数指定,支持多种格式如'YYYY-MM-DD'、'MM/DD/YYYY'等
  • 选择结果的格式与mask参数一致

8.2 时间选择器(Time Input)

时间选择器允许用户选择一个特定的时间。

8.2.1 定义与原理

Time Input基于Quasar的QTime组件,提供了直观的时间选择界面,支持小时和分钟的选择。

8.2.2 语法与参数

ui.time(value=None, mask='HH:mm', on_change=None)

参数

说明

value

初始时间

mask

时间的格式(默认值:'HH:mm')

on_change

当选择了一个时间执行的回调函数

8.2.3 示例代码

from nicegui import ui # 基础时间选择器 ui.time(value='12:00', on_change=lambda e: result1.set_text(f'选择的时间: {e.value}')) result1 = ui.label() # 带秒的时间选择器 ui.time(value='14:30:45', mask='HH:mm:ss', on_change=lambda e: result2.set_text(f'选择的时间: {e.value}')) result2 = ui.label() # 12小时制时间选择器 ui.time(value='03:45 PM', mask='h:mm A', on_change=lambda e: result3.set_text(f'选择的时间: {e.value}')) result3 = ui.label() # 时间选择应用示例 def update_time(e): hours, minutes = map(int, e.value.split(':')) period = '上午' if hours < 12 else '下午' adjusted_hour = hours if 1 <= hours <= 12 else hours - 12 if hours > 12 else 12 time_label.set_text(f'当前选择: {adjusted_hour}点{minutes}分{period}') ui.time(value='09:30', on_change=update_time) time_label = ui.label('当前选择: 9点30分上午') ui.run()

8.2.4 时间格式说明

时间选择器支持多种时间格式:

  • 'HH:mm':24小时制,如'13:45'
  • 'hh:mm A':12小时制,如'01:45 PM'
  • 'HH:mm:ss':带秒的24小时制,如'13:45:30'

9. 文件上传组件(File Upload)

文件上传组件允许用户选择并上传本地文件到服务器。

9.1 定义与原理

File Upload基于Quasar的QUploader组件,提供了文件选择和上传功能,支持多文件上传、文件大小限制等特性。

9.2 语法与参数

ui.upload(multiple=False, max_file_size=0, max_total_size=0, max_files=0,
          on_upload=None, on_multi_upload=None, on_rejected=None, label='',
          auto_upload=False)

参数

说明

multiple

是否允许一次性上传多个文件(默认值:False)

max_file_size

单个文件的最大大小(单位:字节)(默认值:0,表示无限制)

max_total_size

所有文件总大小的上限(单位:字节)(默认值:0,表示无限制)

max_files

最大文件数量限制(默认值:0,表示无限制)

on_upload

每个文件上传完成后执行的回调函数

on_multi_upload

多个文件全部上传完成后执行的回调函数

on_rejected

每个被拒绝的文件执行的回调函数

label

上传组件的标签文字(默认值:'')

auto_upload

选择文件后自动上传(默认值:False)

9.3 示例代码

from nicegui import ui import os # 确保上传目录存在 UPLOAD_DIR = 'uploads' os.makedirs(UPLOAD_DIR, exist_ok=True) # 基础文件上传 def handle_upload(e): # 保存上传的文件 with open(os.path.join(UPLOAD_DIR, e.name), 'wb') as f: f.write(e.content.read()) ui.notify(f'文件 {e.name} 已上传') ui.upload(label='上传文件', on_upload=handle_upload).classes('max-w-full') # 多文件上传 def handle_multi_upload(files): for file in files: with open(os.path.join(UPLOAD_DIR, file.name), 'wb') as f: f.write(file.content.read()) ui.notify(f'{len(files)} 个文件已上传') ui.upload( label='多文件上传', multiple=True, on_multi_upload=handle_multi_upload, auto_upload=True ).classes('max-w-full') # 带限制的文件上传 ui.upload( label='图片上传(最大2MB,最多3个文件)', multiple=True, max_file_size=2 * 1024 * 1024, # 2MB max_files=3, on_upload=lambda e: ui.notify(f'图片 {e.name} 已上传'), on_rejected=lambda e: ui.notify(f'文件 {e.name} 被拒绝: {e.reason}', color='red') ).props('accept=image/*').classes('max-w-full') ui.run()

9.4 注意事项

  • 上传的文件内容通过e.content获取,这是一个类文件对象
  • 使用props('accept=image/*')可以限制文件类型
  • 服务器需要有足够的权限来写入上传的文件
  • 大文件上传可能需要配置服务器的超时时间和最大请求大小

10. 虚拟摇杆(Joystick)

虚拟摇杆提供了一个模拟游戏摇杆的界面,用于获取用户的方向输入。

10.1 定义与原理

虚拟摇杆使用nipple.js库创建,提供了一个可拖动的摇杆界面,用于获取用户的方向和力度输入,适合游戏或远程控制应用。

10.2 语法与参数

ui.joystick(on_start=None, on_move=None, on_end=None, throttle=0.05, options=None)

参数

说明

on_start

当用户开始使用摇杆执行的回调函数

on_move

当用户移动摇杆执行的回调函数

on_end

当用户结束使用摇杆执行的回调函数

throttle

移动事件的节流间隔(单位:秒,默认值:0.05)

options

传递给nipple.js库的参数,如颜色、大小等

10.3 示例代码

from nicegui import ui # 基础虚拟摇杆 coordinates = ui.label('坐标: 0, 0') angle = ui.label('角度: 0°') force = ui.label('力度: 0') ui.joystick( color='blue', size=100, on_move=lambda e: ( coordinates.set_text(f'坐标: {e.x:.2f}, {e.y:.2f}'), ), on_end=lambda _: ( coordinates.set_text('坐标: 0, 0'), angle.set_text('角度: 0°'), force.set_text('力度: 0') ), ).classes('bg-slate-100 p-4') # 限制轴向的摇杆 ui.label('只能在X轴移动的摇杆') x_value = ui.label('X值: 0') ui.joystick( options={'lockY': True}, # 锁定Y轴,只能在X轴移动 on_move=lambda e: x_value.set_text(f'X值: {e.x:.2f}'), on_end=lambda _: x_value.set_text('X值: 0') ).classes('bg-slate-100 p-4') ui.run()

10.4 事件对象属性

摇杆事件对象包含以下主要属性:

  • x:X轴方向的值(范围:-1到1)
  • y:Y轴方向的值(范围:-1到1)
  • angle:包含角度信息的对象,angle.degree为角度值
  • force:力度值(范围:0到1)
  • direction:包含方向信息的对象

10.5 应用场景

  • 网页游戏控制
  • 远程设备控制
  • 方向输入采集
  • 模拟控制器

总结

本文详细介绍了NiceGUI框架中各类控制组件的使用方法,包括按钮、标签、选择组件、布尔值组件、数值输入组件、文本输入组件、颜色选择组件、日期时间组件、文件上传组件和虚拟摇杆。

通过学习这些组件,开发者可以快速构建出功能丰富、交互友好的Web应用界面。NiceGUI的优势在于其简洁的Python API,使得开发者无需深入学习前端技术就能创建专业的Web界面。

在实际开发中,这些组件可以灵活组合使用,结合NiceGUI的布局组件和事件处理机制,能够满足大多数Web应用的需求。建议开发者在掌握基础组件的使用后,进一步学习组件间的数据绑定、状态管理和布局设计,以构建更复杂的应用。

最后,NiceGUI的官方文档提供了更详细的组件说明和示例,开发者可以随时查阅以获取更多信息和灵感。


#编程# #学习# #python#