How to update all label's text properties after changing default_font in Kivy?

34 Views Asked by At

How can I update all of my Kivy widgets to use the new default_font on runtime (without restarting the app)?

I created a Settings screen in my kivy app where a user can select the font that they want the app to use. After the user selects their desired font in the GUI, I update the default_font in Kivy's Config

Config.set('kivy', 'default_font', [font_filename, font_filepath, font_filepath, font_filepath, font_filepath])

When the app restarts, this successfully changes the default font of all my Kivy Labels to the user-slected font.

But how can I have it update all my widgets on all my Screens in my Kivy app on runtime, immediately after the Config.set() call above?

1

There are 1 best solutions below

2
meshkati On

You can iterate over your widgets and change the fonts separately:

from kivy.app import App
from kivy.config import Config
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen

def update_font_recursive(widget):
    if isinstance(widget, Label):
        widget.font_name = Config.get('kivy', 'default_font')[0]
    elif hasattr(widget, 'children'):
        for child in widget.children:
            update_font_recursive(child)

class SettingsScreen(Screen):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # Create your settings screen layout here
        # ...

    def on_font_selected(self, font_filename, font_filepath):
        Config.set('kivy', 'default_font', [font_filename, font_filepath, font_filepath, font_filepath, font_filepath])
        Config.write()
        update_font_recursive(App.get_running_app().root)

class MainScreen(Screen):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # Create your main screen layout here
        # ...

class MyApp(App):
    def build(self):
        sm = ScreenManager()
        sm.add_widget(MainScreen(name='main'))
        sm.add_widget(SettingsScreen(name='settings'))
        return sm

if __name__ == '__main__':
    MyApp().run()