Mesop Button Toggle 组件完全指南:在 Python 中构建单选/多选切换按钮组
【免费下载链接】mesopRapidly build AI apps in Python项目地址: https://gitcode.com/GitHub_Trending/me/mesop
Button toggle(按钮切换组)是 Mesop 基于 Angular Material button toggle 封装的原生组件,用于把一组按钮组织成"互斥单选"或"多选"的切换控件。它非常适合实现富文本工具栏(加粗/斜体/下划线)、筛选条件面板、视图模式切换等交互场景。读完本文,你将掌握me.button_toggle的完整 API、单选/多选/禁用等状态控制、事件回调用法,以及它从 Python 到前端 Angular 的底层数据流实现原理。
Overview:组件是什么
Button toggle 的核心形态是一组并列的按钮,用户点击后按钮进入"选中"高亮状态。它由两个层级组成:
- 组(group):
me.button_toggle本身,负责管理选中状态、多选/单选模式与禁用逻辑; - 按钮(button):组内每个可独立点击的
ButtonToggleButton,包含label(展示文案)与value(选中时上报的值)。
Mesop 中该组件的 Python 侧定义位于 button_toggle.py,通过@register_native_component注册为原生组件,前端由 Angular 的MatButtonToggleModule渲染(见 button_toggle.ts)。
快速上手:完整示例
官方 demo 位于 demo/button_toggle.py,实现了一个典型的"格式工具栏":
from dataclasses import field import mesop as me @me.stateclass class State: selected_values: list[str] = field( default_factory=lambda: ["bold", "underline"] ) def load(e: me.LoadEvent): me.set_theme_mode("system") @me.page( on_load=load, security_policy=me.SecurityPolicy( allowed_iframe_parents=["https://mesop-dev.github.io"] ), path="/button_toggle", ) def app(): state = me.state(State) with me.box(style=me.Style(margin=me.Margin.all(15))): me.button_toggle( value=state.selected_values, buttons=[ me.ButtonToggleButton(label="Bold", value="bold"), me.ButtonToggleButton(label="Italic", value="italic"), me.ButtonToggleButton(label="Underline", value="underline"), ], multiple=True, hide_selection_indicator=False, disabled=False, on_change=on_change, style=me.Style(margin=me.Margin(bottom=20)), ) me.text("Select buttons: " + " ".join(state.selected_values)) def on_change(e: me.ButtonToggleChangeEvent): state = me.state(State) state.selected_values = e.values要点拆解:
- 状态驱动选中:选中值存放在
State.selected_values中(默认选中bold与underline),初始渲染时这两个按钮即为高亮态; value传入的是状态变量,组件是受控的——任何选中变化都会先触发on_change更新状态,再通过状态回流完成界面刷新,这是 Mesop 事件驱动模型的典型用法;- 事件处理器
on_change接收ButtonToggleChangeEvent,从中取出e.values写回状态。
API 详解
button_toggle的函数签名与参数说明如下(摘自 button_toggle.py):
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
value | list[str] \| str | "" | 当前选中的值。传str时会被自动包装为单元素列表 |
buttons | Iterable[ButtonToggleButton] | 必填 | 组内按钮列表 |
on_change | Callable[[ButtonToggleChangeEvent], Any] \| None | None | 组内选中值变化时触发的事件回调 |
multiple | bool | False | 是否允许多选。False为互斥单选模式 |
disabled | bool | False | 是否禁用整个按钮组 |
hide_selection_indicator | bool | False | 是否隐藏选中指示器(勾选标记) |
style | Style \| None | None | 组件样式,如外边距等 |
key | str \| None | None | 组件 key,用于事件溯源,详见 组件 key 说明 |
辅助数据类:ButtonToggleButton
每个按钮由ButtonToggleButton数据类描述,包含两个可选字段(见 button_toggle.py):
label:按钮上展示的文本内容;value:该按钮被选中时上报的取值。
两者均允许为None,实际使用时应保证value唯一,以便事件回调能准确判断用户点了哪个按钮。
事件:ButtonToggleChangeEvent
选中状态变化时触发ButtonToggleChangeEvent,其关键成员(见 button_toggle.py):
values: list[str]:变化后的全部选中值列表;value(属性快捷方式):返回首个选中值;列表为空时返回空字符串""。在单选模式下直接使用e.value即可。
注意:values反映的是整组切换后的完整状态,而非仅变化的单个按钮,因此在多选模式下更新状态时应整体覆盖(如 demo 中的state.selected_values = e.values)。
单选与多选模式
multiple参数决定组的行为模式,官方 e2e 测试分别验证了两种模式(见 button_toggle_test.ts):
单选模式(multiple=False)
单选用例见 single_button_toggle_app.py。此时value适合用单个字符串状态承载:
@me.stateclass class State: selected_value: str = "bold"事件回调使用e.value快捷属性即可拿到当前唯一选中项:
def on_change(e: me.ButtonToggleChangeEvent): state = me.state(State) state.selected_value = e.value该模式下点击按钮会替换当前选中项——点击Italic后,bold自动取消选中,这正是互斥单选的行为(测试中断言点击 Italic 后显示Select button: italic)。
多选模式(multiple=True)
多选用例见 multiple_button_toggle_app.py。value传入list[str],on_change中通过e.values整体覆盖状态:
def on_change(e: me.ButtonToggleChangeEvent): state = me.state(State) state.selected_values = e.values多选模式下点击已选中按钮会将其取消选中(测试中断言再次点击Bold后列表变为underline)。适合做"标签筛选""多条件叠加"类 UI。
禁用与选中指示器
禁用整个组(disabled=True)
disabled=True时,组内所有按钮均不可点击。e2e 的禁用用例见 disabled_button_toggle_app.py 与其测试断言(点击 Bold 后选中值不变)。注意该参数作用于整个组,无法通过本组件 API 单独禁用组内某个按钮;若需要精细化控制,可考虑用me.button自行组装。
隐藏选中指示器(hide_selection_indicator=True)
该参数控制选中态的视觉标记(勾选图标)。在前端模板 button_toggle.ng.html 中,它会同时映射到 Angular Material 的两个输入属性:
<mat-button-toggle-group [hideMultipleSelectionIndicator]="config().getHideSelectionIndicator()" [hideSingleSelectionIndicator]="config().getHideSelectionIndicator()" [multiple]="config().getMultiple()" (change)="onChangeEvent($event)" >即无论单选还是多选,勾选指示器的显隐都由这一个参数统一控制。视觉上更紧凑的工具栏通常设置hide_selection_indicator=True,仅靠高亮底色区分选中态。
底层原理:Python 与 Angular 的数据流
Proto 定义:Python ↔ 前端的契约
组件属性通过 protobuf 传输,契约定义在 button_toggle.proto:
message ButtonToggleType { repeated string value = 1; repeated ButtonToggleButton buttons = 2; optional bool multiple = 3; optional bool disabled = 4; optional bool hide_selection_indicator = 5; optional string on_change_event_handler_id = 6; } message ButtonToggleButton { optional string label = 1; optional string value = 2; } message ButtonToggleChangeEvent { repeated string values = 1; }Python 侧的button_toggle()函数将参数组装为ButtonToggleTypeproto 后调用insert_component注入组件树;其中value经过_format_value_field_proto归一化——空值返回[],字符串被包装成单元素列表(见 button_toggle.py):
def _format_value_field_proto(value: list[str] | str): if not value: return [] if isinstance(value, list): return value return [value]事件回传链路
- 用户在浏览器点击按钮,Angular 触发
MatButtonToggleChange; - 前端 button_toggle.ts 的
onChangeEvent将选中值序列化为ButtonToggleChangeEventproto(字符串值调用addValues,多选数组则循环添加),连同on_change_event_handler_id一起包装成UserEvent通过Channel发送给服务端; - 服务端依据 handler id 找到注册的回调,Python 侧由
map_change_event(button_toggle.py)通过ParseFromString反序列化字节,还原出ButtonToggleChangeEvent(key=..., values=[...])并调用你的on_change函数; - 回调更新
State后,新状态回流前端,isChecked(button_toggle.ts)比对value列表决定每个按钮的checked状态,界面随之刷新。
其中事件类型与映射函数通过register_event_mapper(ButtonToggleChangeEvent, map_change_event)建立关联。
测试验证:行为有据可依
组件行为由 Playwright e2e 测试覆盖(见 button_toggle_test.ts),共三个用例:
| 用例 | 验证点 |
|---|---|
single selection | 单选模式下点击按钮互斥替换,选中值始终为单一项 |
multiple selection | 多选模式下可叠加选中、可取消选中,列表整体更新 |
disabled | 禁用状态下点击不改变选中值 |
这些测试通过page.getByLabel('Bold')等断言驱动真实浏览器交互,验证了从事件触发、状态更新到文本渲染的完整闭环,可作为你自建应用的行为参考基线。
小结
me.button_toggle是 Mesop 构建工具栏、筛选器与视图切换等交互的高频组件。记住三条核心实践:
- 单选用
multiple=False+ 字符串状态 +e.value;多选用multiple=True+ 列表状态 +e.values整体覆盖; - 选中值由状态驱动,务必在
on_change中回写状态,否则组件不会随点击刷新; - 需要紧凑工具栏时开启
hide_selection_indicator=True,需要锁定选项时设置disabled=True。
若需查看实时交互效果,可在仓库中运行 demo 应用访问/button_toggle路由,并参考 demo/button_toggle.py 与 button_toggle.proto 进一步深入。
【免费下载链接】mesopRapidly build AI apps in Python项目地址: https://gitcode.com/GitHub_Trending/me/mesop
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考