Search code examples
python-2.7fontstkintertext-editor

Cannot dynamically change font in python Tkinter text editor


Recently I have been working on a GUI python plain text editor. The code calls this function:

def TimesNewRoman():
    global fontname
    global font
    fontname = "Times New Roman"
    print font

The variables are:

fontname = "Calibri"
size = "14"
font = fontname + " " + size

And Tkinter reads the font with the code:

textPad.config(
    borderwidth=0,
    font=font ,
    foreground="green",
    background="black",
    insertbackground="white", # cursor
    selectforeground="blue", # selection
    selectbackground="#008000",
    wrap="word", 
    width=64,
    undo=True, # Tk 8.4
    )

However, I cannot get it to work. I get no errors but the font remains Calibri. I have searched the internet looking for anything that might allow me to dynamically change the font of the text canvas, but I have not succeeded in finding one that works. Any help in implementing a font modifying feature would be very much appreciated.

I am using python 2.7.7, Tkinter, and I am running this on Windows 7.


Solution

  • Your function should change the font name to "Times New Roman". Are you sure you are calling the function?

    Just for completeness, as also Bryan Oakley stated, you should use the tuple syntax when specifying a font name with more than one word (like I am doing in the example below).

    If it's ok to dynamically change the font of the Text widget with the click of a button, then the following could be a simple solution that uses a Toplevel widget to let the user write the font and size:

    import Tkinter as tk
    
    
    def choose_font():
        global m, text # I hate to use global, but for simplicity
    
        t = tk.Toplevel(m)
        font_name = tk.Label(t, text='Font Name: ')
        font_name.grid(row=0, column=0, sticky='nsew')
        enter_font = tk.Entry(t)
        enter_font.grid(row=0, column=1, sticky='nsew')
        font_size = tk.Label(t, text='Font Size: ')
        font_size.grid(row=1, column=0, sticky='nsew')
        enter_size = tk.Entry(t)
        enter_size.grid(row=1, column=1, sticky='nsew')
    
        # associating a lambda with the call to text.config()
        # to change the font of text (a Text widget reference)
        ok_btn = tk.Button(t, text='Apply Changes',
                           command=lambda: text.config(font=(enter_font.get(), 
                           enter_size.get())))
        ok_btn.grid(row=2, column=1, sticky='nsew')
    
        # just to make strechable widgets
        # you don't strictly need this
        for i in range(2):
            t.grid_rowconfigure(i, weight=1)
            t.grid_columnconfigure(i, weight=1)
        t.grid_rowconfigure(2, weight=1)
    
    
    m = tk.Tk()
    text = tk.Text(m)
    text.pack(expand=1, fill='both')
    chooser = tk.Button(m, text='Choose Font', command=choose_font)
    chooser.pack(side='bottom')
    
    tk.mainloop()
    

    When you click Choose Font, another window shows up, where you can insert the font name and the font size. You can apply the new font name and font size through the click of another Button Apply Changes, which uses a lambda.

    Note that I have not handled any possible wrong inputs (for example inserting a letter for the size), you can do it by your own.