- 前端
- 跨平台
- 桌面应用
- 移动开发
【免费下载链接】flet
Build realtime web, mobile and desktop apps in Python only. No frontend experience required.
ColorScheme 是 Flet 主题系统(Theme)的核心组成部分,它定义了应用中绝大多数控件可用的颜色角色集合。本文基于 Flet 官方类型文档与源码(sdk/python/packages/flet/src/flet/controls/theme.py),系统讲解 ColorScheme 的每个颜色角色的语义、应用方式(全局主题、暗色主题、嵌套主题)以及源码级验证,帮助你用纯 Python 打造风格统一、层次分明、深浅双模式的 Flet 应用界面。
一、ColorScheme 是什么
根据源码中ColorScheme类的文档字符串:
A set of more than 40 colors based on the Material spec that can be used to configure the color properties of most components.
即:ColorScheme 是基于 Material Design 3 颜色体系、由 40 余个颜色角色组成的一套色彩集合,用于配置 Flet 中绝大多数组件(按钮、卡片、输入框、SnackBar、AppBar 等)的颜色属性。
在 Flet 中,ColorScheme是一个用@value装饰器标注的类(从源码结构看,它会被序列化后同步给 Flutter 渲染端,映射到 Flutter 的ColorScheme类)。它定义的每个字段都对应一个 Material 3 的"颜色角色"(color role)——角色不是孤立的颜色值,而是描述颜色在界面中承担什么职责(比如"主要强调色""表面容器色""错误提示色"),并且通常以成对的"背景色 + 前景色"(如primary与on_primary)形式出现,以保证可读性(对比度)。
二、颜色角色速查:核心字段全解析
ColorScheme的每个字段都是Optional[ColorValue],默认值为None(不设置时使用 Flet/Flutter 提供的默认方案)。下面按语义分组介绍全部字段,字段名与源码中的属性名一一对应。
1. Primary 主色系(应用出现最频繁的颜色)
| 字段 | 语义 |
|---|---|
primary | 在应用各屏幕和组件中出现最频繁的颜色,通常是品牌主色 |
on_primary | 绘制在primary之上、且清晰可读的文本/图标颜色 |
primary_container | 用于需要比primary更低强调度的元素(如容器底色) |
on_primary_container | 绘制在primary_container之上且清晰可读的颜色 |
primary_fixed | 明暗主题中保持一致的primary_container替代色 |
primary_fixed_dim | 用于需要比primary_fixed更高强调度的元素 |
on_primary_fixed | 绘制在primary_fixed之上用于文本和图标的颜色 |
on_primary_fixed_variant | 比on_primary_fixed强调度更低的文本/图标颜色 |
2. Secondary 次色系(次要强调色)
| 字段 | 语义 |
|---|---|
secondary | 用于 UI 中较次要的组件(如筛选Chip)的强调色,扩展色彩表达空间 |
on_secondary | 绘制在secondary之上且清晰可读的颜色 |
secondary_container | 用于需要比secondary更低强调度的元素 |
on_secondary_container | 绘制在secondary_container之上且清晰可读的颜色 |
secondary_fixed/secondary_fixed_dim | 明暗主题一致的secondary_container替代色及其更高强调度版本 |
on_secondary_fixed/on_secondary_fixed_variant | 绘制在secondary_fixed之上(含低强调度变体)的文本/图标颜色 |
3. Tertiary 第三色系(对比强调色)
| 字段 | 语义 |
|---|---|
tertiary | 用于平衡primary、secondary的对比强调色,或吸引用户对特定元素(如输入框)的注意 |
on_tertiary | 绘制在tertiary之上且清晰可读的颜色 |
tertiary_container | 用于需要比tertiary更低强调度的元素 |
on_tertiary_container | 绘制在tertiary_container之上且清晰可读的颜色 |
tertiary_fixed/tertiary_fixed_dim | 明暗主题一致的tertiary_container替代色及其更高强调度版本 |
on_tertiary_fixed/on_tertiary_fixed_variant | 绘制在tertiary_fixed之上(含低强调度变体)的文本/图标颜色 |
4. Error 错误色系(校验与错误提示)
| 字段 | 语义 |
|---|---|
error | 输入校验错误等场景使用的颜色,例如FormFieldControl.error的提示色 |
on_error | 绘制在error之上且清晰可读的颜色 |
error_container | 用于需要比error更低强调度的错误元素 |
on_error_container | 绘制在error_container之上且清晰可读的颜色 |
5. Surface 表面色系(背景与层次)
| 字段 | 语义 |
|---|---|
surface | 类似Card等组件的背景色 |
on_surface | 绘制在surface之上且清晰可读的颜色 |
on_surface_variant | 绘制在surface_container_highest之上且清晰可读的变体颜色 |
surface_bright | 无论明暗主题都最亮的表面颜色 |
surface_dim | 无论明暗主题都最暗的表面颜色 |
surface_tint | 叠加在表面色上、用于指示组件高度(elevation)的颜色 |
surface_container | 表面内某个独立区域的推荐颜色角色 |
surface_container_low/surface_container_lowest | 色调更亮、强调度更低的表面容器色(lowest最亮、强调度最低) |
surface_container_high/surface_container_highest | 色调更暗的表面容器色(highest最暗,相对surface强调度最高) |
6. 其他实用角色
| 字段 | 语义 |
|---|---|
outline | 创建边界和强调、提升可用性的实用颜色 |
outline_variant | 无需 3:1 对比度时的装饰性边界颜色(如分割线、装饰元素) |
shadow | 用于绘制抬升组件投影的颜色 |
scrim | 用于绘制模态组件周围遮罩(scrim)的颜色 |
inverse_surface | 与周围 UI 相反的表面色,例如SnackBar中用于突出警报的背景 |
on_inverse_surface | 绘制在inverse_surface之上且清晰可读的颜色 |
inverse_primary | 在inverse_surface背景上使用的强调色,如SnackBar中的按钮文字颜色 |
三、如何应用 ColorScheme:全局主题
ColorScheme通常不单独使用,而是赋值给Theme的color_scheme属性,再挂到Page上。Page(控件树最顶层的控件)提供了两个相关属性:
page.theme:应用在浅色模式下的全局主题;page.dark_theme:应用在深色模式下的全局主题。
两者类型均为Theme,代表应用范围内的默认/兜底主题,除非在控件树中被显式覆盖。官方 Cookbook(website/docs/cookbook/theming.md)给出最简用法:
import flet as ft def main(page: ft.Page): page.theme = ft.Theme(color_scheme_seed=ft.Colors.GREEN) page.dark_theme = ft.Theme(color_scheme_seed=ft.Colors.BLUE) ft.run(main)方式一:手动配置完整 ColorScheme
当你需要精确控制每个颜色角色时,直接构造ft.ColorScheme(...):
import flet as ft def main(page: ft.Page): page.theme = ft.Theme( color_scheme=ft.ColorScheme( primary=ft.Colors.GREEN, on_primary=ft.Colors.WHITE, primary_container=ft.Colors.GREEN_900, on_primary_container=ft.Colors.WHITE, secondary=ft.Colors.BLUE, on_secondary=ft.Colors.WHITE, secondary_container=ft.Colors.BLUE_900, on_secondary_container=ft.Colors.WHITE, tertiary=ft.Colors.RED, on_tertiary=ft.Colors.WHITE, tertiary_container=ft.Colors.RED_900, on_tertiary_container=ft.Colors.WHITE, error=ft.Colors.RED, error_container=ft.Colors.RED_900, on_error=ft.Colors.WHITE, on_error_container=ft.Colors.WHITE, surface=ft.Colors.ORANGE_400, on_surface=ft.Colors.BLACK, on_surface_variant=ft.Colors.RED, surface_bright=ft.Colors.ORANGE_200, surface_dim=ft.Colors.ORANGE_600, surface_container=ft.Colors.ORANGE, surface_container_low=ft.Colors.ORANGE_100, surface_container_lowest=ft.Colors.ORANGE_50, surface_container_high=ft.Colors.ORANGE_300, surface_container_highest=ft.Colors.ORANGE_500, surface_tint=ft.Colors.GREEN, shadow=ft.Colors.BLACK, scrim=ft.Colors.BLACK, outline=ft.Colors.BLUE_200, outline_variant=ft.Colors.BLUE_400, inverse_surface=ft.Colors.BLACK, on_inverse_surface=ft.Colors.WHITE, inverse_primary=ft.Colors.GREEN_900, primary_fixed=ft.Colors.GREEN_400, primary_fixed_dim=ft.Colors.GREEN_700, on_primary_fixed=ft.Colors.WHITE, on_primary_fixed_variant=ft.Colors.WHITE, secondary_fixed=ft.Colors.BLUE_400, secondary_fixed_dim=ft.Colors.BLUE_700, on_secondary_fixed=ft.Colors.WHITE, on_secondary_fixed_variant=ft.Colors.WHITE, tertiary_fixed=ft.Colors.RED_400, tertiary_fixed_dim=ft.Colors.RED_700, on_tertiary_fixed=ft.Colors.WHITE, on_tertiary_fixed_variant=ft.Colors.WHITE, ) ) ft.run(main)上述示例中的字段组合在官方集成测试(sdk/python/packages/flet/integration_tests/controls/theme/test_color_scheme.py)中被完整使用,可视为一份可运行的"全字段"参考。
方式二:用 color_scheme_seed 快速生成
如果不想逐一指定 40 多个角色,可以只给Theme.color_scheme_seed传一个种子颜色,由 Material 3 的动态配色算法自动生成整套ColorScheme。源码注释明确说明(theme.py):
Overrides the default color scheme seed used to generate
ColorScheme. The default color is blue.
即默认种子色为蓝色(blue),覆盖后整套角色会围绕你给出的种子色生成:
import flet as ft def main(page: ft.Page): page.theme = ft.Theme(color_scheme_seed=ft.Colors.INDIGO) page.dark_theme = ft.Theme(color_scheme_seed=ft.Colors.TEAL) ft.run(main)这种方式适合快速换肤、原型开发;需要精确控制对比度与品牌色时,再回退到方式一。
四、嵌套主题:让局部区域使用独立配色
Flet 允许应用的不同区域使用不同主题。部分容器类控件带有theme和theme_mode属性(类型分别为Theme与ThemeMode):
- 指定
theme_mode表示不再继承父级主题模式,容器内部所有控件使用全新的独立配色方案; - 若未设置
theme_mode,则theme中配置的样式会覆盖继承自父级主题的对应样式。
官方 Cookbook(website/docs/cookbook/theming.md)中的完整示例:
import flet as ft def main(page: ft.Page): # 黄色页面主题,模式为 SYSTEM(默认) page.theme = ft.Theme( color_scheme_seed=ft.Colors.YELLOW, ) page.add( # 使用页面主题 ft.Container( content=ft.Button("Page theme button"), bgcolor=ft.Colors.SURFACE_CONTAINER_HIGHEST, padding=20, width=300, ), # 继承主题,但覆盖 primary 颜色 ft.Container( theme=ft.Theme(color_scheme=ft.ColorScheme(primary=ft.Colors.PINK)), content=ft.Button("Inherited theme button"), bgcolor=ft.Colors.SURFACE_CONTAINER_HIGHEST, padding=20, width=300, ), # 完全独立的常驻 DARK 主题 ft.Container( theme=ft.Theme(color_scheme_seed=ft.Colors.INDIGO), theme_mode=ft.ThemeMode.DARK, content=ft.Button("Unique theme button"), bgcolor=ft.Colors.SURFACE_CONTAINER_HIGHEST, padding=20, width=300, ), ) ft.run(main)这个例子展示了三种层级:全局继承、局部覆盖(只改primary)、局部独立(独立种子色 + 强制暗色模式),是理解 Flet 主题继承机制的最佳入口。
五、颜色角色的源码实现与验证
1. 定义位置与数据结构
ColorScheme定义在sdk/python/packages/flet/src/flet/controls/theme.py,类上使用@value装饰器。从源码结构看,@value装饰的类会被转换为可序列化/可比较的值对象,Flet 服务端将其作为主题配置的一部分同步给 Flutter 渲染端,最终映射为 Flutter Material 的ColorScheme。类中所有字段均为Optional[ColorValue]且默认None,意味着你只需设置关心的角色,其余角色继续使用默认配色——这让"局部覆盖"(如上例只改primary)成为可能。
2. Theme 的挂载点
Theme类(theme.py#L3281)中与配色直接相关的属性包括:
color_scheme: Optional[ColorScheme]:覆盖应用默认的 ColorScheme;color_scheme_seed: Optional[ColorValue]:用种子色自动生成 ColorScheme,默认蓝色;use_material3: Optional[bool]:临时开关,可用来退出 Material 3 特性(即退回 Material 2 的配色习惯)。
此外Theme还包含appbar_theme、card_theme、chip_theme、button_theme、dialog_theme、divider_color等大量组件级主题属性,ColorScheme与它们协同构成完整的主题体系。
3. 集成测试佐证
仓库中针对 ColorScheme 的集成测试(sdk/python/packages/flet/integration_tests/controls/theme/test_color_scheme.py)验证了三点:
- 全字段可配置:测试一次性设置了
ColorScheme的 40+ 个角色,证明所有字段在运行时可被接受并生效(test_theme_1中flet_app.page.theme = ft.Theme(color_scheme=ft.ColorScheme(...))); - 角色驱动组件渲染:测试用
ft.Screenshot捕获了主色板、次色板、第三色板、表面角色、强调角色、按钮组、主题卡片、错误横幅等区域,逐一断言截图,直观验证各颜色角色在按钮(FilledButton/FilledTonalButton/OutlinedButton/TextButton/IconButton/FloatingActionButton)、Card、ListTile、Switch、错误横幅上的实际呈现效果; - 颜色角色可编程引用:测试中大量使用
ft.Colors.PRIMARY、ft.Colors.ON_PRIMARY、ft.Colors.SURFACE_CONTAINER_HIGHEST、ft.Colors.ERROR_CONTAINER等常量——这些常量与ColorScheme的角色名一一对应,说明控件可以直接通过ft.Colors.*常量引用当前主题中的角色颜色。
六、实践建议与注意事项
- 成对设置,保证对比度:Material 3 的每个背景角色都有对应的
on_*前景角色(如primary/on_primary、surface/on_surface、error_container/on_error_container)。设置背景色时请同步设置其on_*颜色,否则文本可能不可读。 - 深浅模式分别配置:利用
page.theme(浅色)与page.dark_theme(深色)分别提供两套ColorScheme,Flet 会根据系统/页面模式自动切换,无需在业务代码里手动判断。 - 优先用
color_scheme_seed起步:Material 3 的种子配色算法会自动生成和谐的整套角色(包括 surface 层次、fixed 系列等),手工全量配置容易遗漏某个角色导致局部"跳出"整体风格。 - 局部覆盖是合法的主题化手段:通过容器
theme属性只覆盖少量角色(如把某个区域的primary换成强调色),比另起一套完整主题更轻量、更易维护。 - 理解 Material 3 与 Material 2 差异:源码中
use_material3仍作为"临时开关"保留;当前ColorScheme的角色命名(surface_container_*、*_fixed系列)遵循 Material 3 规范,如果你的应用追求 M2 风格,需要了解这一命名体系的差异。
通过 ColorScheme,你可以在不接触任何前端代码的情况下,用纯 Python 完成从"品牌主色"到"明暗双主题"再到"局部独立配色"的完整主题化工作流,这也是 Flet "仅用 Python 构建跨端应用"理念在视觉层的最佳体现。
- 前端
- 跨平台
- 桌面应用
- 移动开发
【免费下载链接】flet
Build realtime web, mobile and desktop apps in Python only. No frontend experience required.
相关推荐
bufferline.nvim 与 colorscheme 的完美搭配:色彩定制完全指南
bufferline.nvim 与 colorscheme 的完美搭配:色彩定制完全指南 想要让你的 Neovim 界面更加专业美观吗? bufferline.
Material Components Web 主题系统完全指南:使用 @material/theme 实现品牌化配色与无障碍色彩
Material Components Web 主题系统完全指南:使用 @material/theme 实现品牌化配色与无障碍色彩 Material Compo
前端UI组件设计系统尖峰平谷灵活定价:HUIZHI-ChargeOS-cloud分时计费规则设计完整拆解
尖峰平谷灵活定价:HUIZHI ChargeOS cloud分时计费规则设计完整拆解 尖峰平谷分时计费,是充电运营平台控制成本、提升收益的核心能力。 HUIZH
后端物联网智能硬件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考