Flet 字体粗细完全指南:深入理解 flet.FontWeight 枚举与文本渲染原理
2026/9/23 22:38:41 网站建设 项目流程
  • 前端
  • 跨平台
  • 桌面应用
  • 移动开发

【免费下载链接】flet

Build realtime web, mobile and desktop apps in Python only. No frontend experience required.

项目地址:https://gitcode.com/gh_mirrors/fl/flet
点击查看免费下载

本文以 Flet 官方类型文档 fontweight.md 为核心,系统讲解flet.FontWeight枚举的全部取值、在TextTextStyle中的使用方式,以及它在 Flet 客户端(Flutter/Dart)侧的底层映射与可变字体(variable font)支持。读完本文,你将能够在 Flet 应用中精确控制任意文本的字重,实现从极细(Thin)到特粗(Black)的完整字重梯度,并能借助源码理解weight参数在 Python 与 Dart 之间的传递与解析机制。

FontWeight 是什么

FontWeight是 Flet 中用于描述"绘制文本时字形(glyph)粗细程度"的枚举类型,对应 Flutter 中的FontWeight概念。在 Flet 的 Python 类型体系中,它定义于 types.py:

class FontWeight(Enum): """ The thickness of the glyphs used to draw the text. """ NORMAL = "normal" """ The default font weight, equal to `w400`. """ BOLD = "bold" """ A commonly used font weight that is heavier than normal, equal to `w700`. """ # ... 其余成员见下文表格

从定义可以看出,FontWeight底层是基于str的枚举:每个成员在 Python 端有一个语义化的名称(如NORMALBOLD),对应的字符串值(如"normal""bold")则是 Python 端与 Flet 客户端(Flutter/Dart)通信时使用的协议值。这也意味着在 Flet 中,weight属性既接受枚举成员,也接受与其等价的字符串字面量。

全部枚举成员一览

FontWeight共包含 11 个成员,覆盖了从最细到最粗的完整字重梯度。其中NORMALBOLD是语义别名,其余 9 个成员以W_前缀 + 数字命名,直接对应 CSS / Flutter 中广泛使用的w100w900数字体系:

枚举成员字符串值说明
FontWeight.NORMAL"normal"默认字重,等价于w400
FontWeight.BOLD"bold"常用加粗字重,等价于w700
FontWeight.W_100"w100"Thin,最细
FontWeight.W_200"w200"Extra-light,超细
FontWeight.W_300"w300"Light,细体
FontWeight.W_400"w400"Normal / Regular / Plain,常规
FontWeight.W_500"w500"Medium,中等
FontWeight.W_600"w600"Semi-bold,半粗
FontWeight.W_700"w700"Bold,粗体
FontWeight.W_800"w800"Extra-bold,特粗
FontWeight.W_900"w900"Black,最粗

以上成员及其文档字符串均来自 types.py 的源码定义,例如W_100的注释为 "Thin, the least thick",W_900的注释为 "Black, the most thick"。值得注意的是,NORMALW_400BOLDW_700只是同一个字重的两种命名方式,实际渲染效果相同。

在 Text 控件中使用 weight

FontWeight最常见的应用场景是Text控件的weight参数。在 text.py 中,该参数的类型签名如下:

weight: Optional[FontWeight] = None

未显式指定时默认为None,此时渲染使用主题的默认字重(通常是NORMAL/w400)。显式传入枚举成员即可改变字重:

import flet as ft def main(page: ft.Page): page.add( ft.Column( controls=[ ft.Text("默认字重(Normal)", size=20), ft.Text("加粗(Bold)", size=20, weight=ft.FontWeight.BOLD), ft.Text("中等(Medium)", size=20, weight=ft.FontWeight.W_500), ft.Text("最细(Thin)", size=20, weight=ft.FontWeight.W_100), ft.Text("最粗(Black)", size=20, weight=ft.FontWeight.W_900), ] ) ) ft.run(main)

由于枚举底层是字符串,weight也接受等价字符串字面量,例如weight="bold"weight="w600",效果与对应枚举成员一致。这在需要从配置文件或外部数据动态传入字重时非常方便。

官方对照示例:一屏预览全部字重

Flet 官方为FontWeight类型提供了完整的可运行对照示例,位于 sdk/python/examples/controls/core/types/font_weight/showcase/main.py。该示例将ft.FontWeight的 11 个成员逐一渲染成卡片,方便直观对比各字重的视觉差异:

import flet as ft SAMPLE_TEXT = "Sphinx of black quartz" def showcase_card(weight: ft.FontWeight) -> ft.Container: return ft.Container( width=300, padding=12, border=ft.Border.all(1, ft.Colors.RED), border_radius=10, bgcolor=ft.Colors.SURFACE_CONTAINER_LOW, content=ft.Column( spacing=8, controls=[ ft.Text(weight.name, size=12, color=ft.Colors.ON_SURFACE_VARIANT), ft.Text(SAMPLE_TEXT, weight=weight, size=24), ], ), ) def main(page: ft.Page): page.horizontal_alignment = ft.CrossAxisAlignment.CENTER page.appbar = ft.AppBar(title="FontWeight Showcase") page.add( ft.SafeArea( expand=True, content=ft.Column( controls=[ ft.Text("Compare text thickness across all FontWeight values."), ft.Row( wrap=True, spacing=12, expand=True, scroll=ft.ScrollMode.AUTO, alignment=ft.MainAxisAlignment.CENTER, controls=[showcase_card(weight) for weight in ft.FontWeight], ), ], ), ) ) if __name__ == "__main__": ft.run(main)

这段代码有几个值得学习的点:

  • 遍历枚举for weight in ft.FontWeight直接遍历枚举成员,自动生成 11 张卡片,无需手写重复代码;
  • 动态传参ft.Text(SAMPLE_TEXT, weight=weight, size=24)把枚举成员直接传给weight参数;
  • 展示枚举名weight.name取出枚举成员的名称(如W_100)显示在卡片顶部作为标签;
  • 自适应布局ft.Row配合wrap=Truescroll=ft.ScrollMode.AUTO,让卡片在小窗口下自动换行、超出时滚动。

运行方式与普通 Flet 应用一致:flet run该文件或在本地执行python main.py

进阶:可变字体(Variable Font)下的动态字重

固定枚举值之外,Flet 的weight参数还支持以字符串形式传入w前缀 + 任意数字的写法(如"w350""w620"),配合支持wght轴的可变字体,可以实现字重的平滑连续调节。官方示例 variable_font_weight/main.py 展示了这一能力——通过一个 Slider 实时改变文本字重:

import flet as ft def main(page: ft.Page): page.fonts = { "RobotoSlab": "https://github.com/google/fonts/raw/main/apache/robotoslab/RobotoSlab%5Bwght%5D.ttf" } def handle_slider_change(e): text.weight = f"w{int(e.control.value)}" # noqa text.update() page.add( ft.SafeArea( content=ft.Column( controls=[ text := ft.Text( "This is rendered with Roboto Slab", size=30, font_family="RobotoSlab", weight=ft.FontWeight.W_100, ), ft.Slider( min=100, max=900, divisions=8, label="Weight = {value}", width=500, on_change=handle_slider_change, ), ], ), ), ) if __name__ == "__main__": ft.run(main)

该示例的关键点:

  • 通过page.fonts注册一个包含wght轴的可变字体(Roboto Slab);
  • ft.Textweight初始为W_100,使用 Walrus 运算符:=将控件实例捕获到变量text中;
  • 滑块变化时执行text.weight = f"w{int(e.control.value)}",动态拼接字符串字重(w100w900)并调用text.update()刷新界面。

需要说明的是,这种连续字重效果依赖字体本身是否提供对应的字重档位:若字体只包含离散字重(如常规 400 与粗体 700),中间值会被就近映射;可变字体则能提供真正的平滑过渡。

底层原理:weight 如何映射到 Flutter

FontWeight的 Python 枚举值最终会通过 Flet 协议发送到客户端(Flutter/Dart)渲染。Dart 端的解析函数位于 utils/text.dart:

FontWeight? parseFontWeight(String? weightName, [FontWeight? defaultWeight]) { if (weightName == null) return defaultWeight; final weights = <String, FontWeight>{ "normal": FontWeight.normal, "bold": FontWeight.bold, "w100": FontWeight.w100, "w200": FontWeight.w200, "w300": FontWeight.w300, "w400": FontWeight.w400, "w500": FontWeight.w500, "w600": FontWeight.w600, "w700": FontWeight.w700, "w800": FontWeight.w800, "w900": FontWeight.w900, }; return weights[weightName.toLowerCase()] ?? defaultWeight; }

可以看到,Dart 端建立了一张与 Python 枚举完全对应的映射表:"normal"FontWeight.normal"bold"FontWeight.bold"w100"FontWeight.w100…… 依此类推,并且解析前会统一转小写,保证大小写不敏感。若传入未知值或null,则回退到defaultWeight

Text控件的渲染逻辑在 controls/text.dart 中还有一处特殊处理:

var fontWeight = control.getString("weight", "")!; if (fontWeight.startsWith("w")) { // 以 "w" 开头的字重会额外生成 FontVariation('wght', ...), // 从而支持可变字体(variable font)的 wght 轴 ...add(FontVariation('wght', parseDouble(fontWeight.substring(1), 0)!)); } fontWeight: parseFontWeight(fontWeight),

这段代码揭示了一个重要实现细节:当weight字符串以w开头时(无论是w400还是w620),Dart 端除了设置fontWeight外,还会额外注册一个FontVariation('wght', 数值)。这正是上一节"动态字重"得以实现的原因——wght轴的变化量会被直接传递给支持可变字体的引擎。此外,TextStyle、表单字段等涉及文本样式的场景也复用了同一套解析逻辑,见 utils/form_field.dart 与 controls/text_style.dart。

使用建议与注意事项

结合源码与示例,使用FontWeight时有几点值得注意:

  1. 优先使用枚举成员:在静态代码中建议使用ft.FontWeight.W_600这类枚举写法,可读性强且能被 IDE 自动补全与类型检查;仅在数据驱动场景(如读取配置、用户输入)下使用字符串字面量。
  2. 别名等价NORMAL == W_400BOLD == W_700,二者渲染结果完全相同,按语义选一个即可。
  3. 字重依赖字体:最终显示效果取决于所用字体是否内置对应字重。系统默认字体通常只有 regular(400)与 bold(700)两个档位,中间字重会就近映射;要获得完整梯度或连续变化,需要加载包含多字重或wght轴的可变字体(参考 可变字体示例)。
  4. 默认值行为Text.weight默认None,此时沿用主题默认字重;显式传FontWeight.NORMAL与不传在多数主题下效果一致。
  5. 调试辅助:官方 FontWeight Showcase 是检查当前字体支持哪些字重档位的快捷手段,改换字体后运行一遍即可直观对比。

小结

flet.FontWeight是 Flet 文本渲染体系中最基础也最常用的类型之一:Python 端通过 11 个枚举成员(NORMALBOLDW_100W_900)描述字形粗细,字符串值在 Dart 端被 parseFontWeight 映射为 Flutter 的FontWeight,而w前缀写法还额外触发FontVariation('wght', ...)以支持可变字体的连续字重。掌握了枚举定义、示例用法与底层解析链路,你就能在任何 Flet 应用中精准、灵活地控制文本观感。

  • 前端
  • 跨平台
  • 桌面应用
  • 移动开发

【免费下载链接】flet

Build realtime web, mobile and desktop apps in Python only. No frontend experience required.

项目地址:https://gitcode.com/gh_mirrors/fl/flet
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询