
通过递归遍历应用根节点下的所有子控件,定位 Label 实例并手动同步 font_name 为当前 Config 中的 default_font,即可实现在不重启应用的前提下实时刷新全部文本控件的字体。
通过递归遍历应用根节点下的所有子控件,定位 label 实例并手动同步 `font_name` 为当前 config 中的 `default_font`,即可实现在不重启应用的前提下实时刷新全部文本控件的字体。
在 Kivy 中,Config.set('kivy', 'default_font', ...) 仅影响新创建的控件(如后续动态生成的 Label),对已渲染的现有 Label 控件无即时作用——这是因为 default_font 是初始化时读取的配置项,而非运行时绑定的动态属性。因此,必须主动更新已有 Label 的 font_name 属性。
推荐采用递归遍历方式统一刷新字体。以下是一个健壮、可复用的实现方案:
from kivy.app import App
from kivy.config import Config
from kivy.uix.label import Label
from kivy.uix.widget import Widget
def update_font_recursive(widget):
"""递归更新 widget 及其所有子孙中所有 Label 的 font_name"""
if isinstance(widget, Label):
# 注意:Config.get 返回的是字符串或列表;default_font 配置值为 [family, fn1, fn2, fn3, fn4]
# 其中 family(字体族名)位于索引 0,通常即为实际使用的字体文件路径或系统字体名
font_config = Config.get('kivy', 'default_font')
if isinstance(font_config, list) and len(font_config) > 0:
widget.font_name = font_config[0]
else:
widget.font_name = str(font_config) # 兜底处理(如配置为单字符串)
elif hasattr(widget, 'children') and callable(getattr(widget, 'children', None)):
for child in widget.children:
update_font_recursive(child)⚠️ 关键注意事项:
- Config.write() 必须调用,确保配置持久化(否则重启后失效);
- App.get_running_app().root 是当前主窗口的根控件(如 ScreenManager),务必确保它已构建完成(即在 on_start 或用户操作回调中调用);
- 若项目中使用了自定义文本控件(如继承自 Label 的 StyledLabel),需将 isinstance(widget, Label) 扩展为 isinstance(widget, (Label, YourCustomLabel));
- 对于 TextInput、Button 等也依赖字体的控件,可按需扩展判断逻辑(例如增加 elif isinstance(widget, TextInput) 分支);
- 避免在 __init__ 中过早调用 update_font_recursive,此时 root 可能尚未赋值,建议在 on_font_selected 或 on_enter 等生命周期回调中触发。
在设置页中应用该逻辑示例:
class SettingsScreen(Screen):
def on_font_selected(self, font_filename, font_filepath):
# 设置 default_font(支持完整五元组:family, regular, bold, italic, bold_italic)
Config.set('kivy', 'default_font', [
font_filename,
font_filepath, # regular
font_filepath, # bold(可替换为 bold 版本路径)
font_filepath, # italic
font_filepath # bold_italic
])
Config.write() # 持久化配置
# 立即刷新全部已存在 Label
app = App.get_running_app()
if app and app.root:
update_font_recursive(app.root)此方法轻量、兼容性强,无需重载 Label 类或侵入式修改 Kivy 内核,是生产环境中推荐的动态字体切换实践。

















