Search code examples
pythonpython-3.xtkinterttkbootstrap

Tkinter/Ttkbootstrap Font Size After Theme Change


I'm probably just missing something obvious here but I've tried everything I know of. In my application, the user can change the theme by selecting it from a Combobox, and the theme changes. The unwanted behavior is that the font size also changes back to the default. I've tried resetting it after the theme change but the only way I can find to do it would be to destroy the entire instance and reload everything which is not preferable. Any suggestions?

I also noticed that the font size does go back to what it was set to when the theme is switched to the originally set theme. I.e. if I had it set to font size 12 and the theme as darkly when the application was first started, then the font size will go to the default when the theme is changed to anything else but will go to 12 when darkly is selected again.

Here's a MWE:

import tkinter as tk
import ttkbootstrap as tb

def change_theme(event):
    t = combo.get()
    style.theme_use(t)

app = tb.Window(title='Font Weirdness',
        themename='darkly')

style = app.style
style.configure('.', font=('TkDefaultFont', 20))                                                        
button = tb.Button(app, text='Hello')
button.pack(pady=20)

combo = tb.Combobox(app, values=tb.Style().theme_names())
combo.pack(pady=20)

combo.bind('<<ComboboxSelected>>', change_theme)

app.position_center()

app.mainloop()

Thanks for any help!


Solution

  • The problem is that you're giving the current style a custom font that only applies to that style. When you do font=('TkDefaultFont', 20) you are creating a new font based on the family "TkDefaultFont". That's not a valid font family so the custom font will end up being based on the default font. The actual default font remains unchanged.

    If you want to define the font once and have it be the same for all styles, you need to modify the actual default font. You can use nametofont to get the actual font object. You can then change the size of that font object with configure:

    from tkinter.font import nametofont
    ...
    default_font = nametofont("TkDefaultFont")
    default_font.configure(size=30)
    ...
    

    With that, you can remove your style.configure statement and all styles that use TkDefaultFont properly will use your new definition.