How can I change the default font of a Tkinter application during the mainloop?

Viewed 1237

How can I change the default font of a Tkinter application during the mainloop?

I would like to have a button in my application where the user can increase or decrease the font of all the widgets. Currently, I'm just changing the default font size of root right at the beginning, but I haven't been able to modify the font size after the application is running.

I'm aware that Tkinter allows you to change the default using root.option_add("*Font", font), but how can modify the font while the application is running?

Here is an example of what I am trying to do:

import tkinter as tk

class Application(tk.Frame):

    def __init__(self, master=None):
        super().__init__(master, bg= "#E3E5E6")
        self.master = master
        
        self.grid(sticky = "NESW")
        
        
        self.menubar = tk.Menu(self)
        
        
        fileMenu = tk.Menu(self.menubar)
        fileMenu.add_command(label="Change Font Size", command =self.changeFontSize)
      
        self.menubar.add_cascade(label = "Click Me", menu = fileMenu)
        
        self.master.configure(menu=self.menubar)

        text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."

        self.messageWidgetExample = tk.Message(text = text)
        self.messageWidgetExample.grid()
      
    def changeFontSize(self):
        print("Change Font Size")
        self.master.option_add("*Font", "calibri 8") 
        self.master.update()

        # Doesn't work either
        # self.messageWidgetExample.update()
     
root = tk.Tk()

root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
root.option_add("*Font", "calibri 14")
    
app = Application(master=root)
app.mainloop()
1 Answers

The easiest way is to get a reference to the default font object. When you reconfigure it, every widget using that font will adjust automatically.

Here's a contrived example that includes two buttons, a label, and a text widget. The buttons and label use the default font automatically, the text widget defaults to a different font, so we will explicitly set it to the default.

import tkinter as tk
from tkinter import font

def zoom_in():
    size = default_font.cget("size")
    default_font.configure(size=size+2)

def zoom_out():
    size = default_font.cget("size")
    default_font.configure(size=max(size-2, 8))

root = tk.Tk()
root.geometry("400x300")
default_font = tk.font.nametofont("TkDefaultFont")

toolbar = tk.Frame(root)
# start small, but then expand to fill the window.
# Doing this, and fixing the size of the window will
# prevent the window from growing or shrinking when
# we change the font.
text = tk.Text(root, width=1, height=1, font=default_font)
print(text.cget("font"))

toolbar.pack(side="top", fill="x", ipady=4)
text.pack(side="bottom", fill="both", expand=True)

zoom_in = tk.Button(toolbar, text="Zoom In", command=zoom_in)
zoom_out = tk.Button(toolbar, text="Zoom Out", command=zoom_out)
label = tk.Label(toolbar, text="Change font size:")
label.pack(side="left")
zoom_in.pack(side="left")
zoom_out.pack(side="left")

text.insert("end", "Hello, world")
root.mainloop()

By default, the window looks like this:

screenshot of initial window

This is what it looks like after clicking the "Zoom In" button a few times:

screenshot after zooming in

Related