0

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.

Pseudonym Enigma
  • 129
  • 1
  • 2
  • 14
  • Your code works for me. Are you sure you are going to the menu `Configuration` > `Change Font`? – nbro Feb 06 '15 at 03:18
  • When posting code, it's best to remove as much code as possible while still being able to reproduce the problem. We don't need the functions cut, copy, past, find, undo and so on to reproduce the problem. Your question would be better if you removed everything you possibly can, while still leaving a runnable program that has the behavior you describe. – Bryan Oakley Feb 06 '15 at 03:27
  • I don't see anywhere in the code you posted where you're trying to change the font to "Times New Roman". – Bryan Oakley Feb 06 '15 at 03:28
  • Times New Roman was an example. I was planning on expanding it so that I could change the text to a variety of fonts. Also, yes, I am sure that I went to the menu configuration and then change fonts. – Pseudonym Enigma Feb 06 '15 at 03:59

2 Answers2

1

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.

Community
  • 1
  • 1
nbro
  • 15,395
  • 32
  • 113
  • 196
  • Thank you for the code. However, all it does is re-size the text window. The font and the actual size of the text do not change. – Pseudonym Enigma Feb 06 '15 at 02:58
  • @PseudonymEnigma For me it resizes the font of the `Text` widget. Are you sure your code is exactly the same? By the way, why are you using a Canvas? If you post all your code, I can try to help more. – nbro Feb 06 '15 at 03:01
  • Thank you for your answer and the explanation about the use of tuples. However, it does not solve the problem. – Pseudonym Enigma Feb 06 '15 at 03:04
  • @PseudonymEnigma Please, post all your code, and I will try to solve the problem – nbro Feb 06 '15 at 03:05
  • I am using a ScrolledText and a Text at the same time in order to easily add a scrollbar. – Pseudonym Enigma Feb 06 '15 at 04:07
  • @PseudonymEnigma You can simply use `ScrolledText` instead of `Text`. By the way, have you managed to change the font? – nbro Feb 06 '15 at 04:09
  • Thank you for the tip, and no, I have not. Also, I removed unnecessary functions from my code. – Pseudonym Enigma Feb 06 '15 at 04:23
  • @PseudonymEnigma I am using Python 3 and I have converted your code to Python 3 using the `2to3` tool, but it should also work in Python 2. Does the Top-level for changing the font at least appears? – nbro Feb 06 '15 at 04:25
  • Yes, everything seems as if it should work, however the font does not change. – Pseudonym Enigma Feb 06 '15 at 04:26
  • I really cannot understand why, unless I see it working. For me, when I click `Apply Changes`, the new font is applied to the `Text` widget... – nbro Feb 06 '15 at 04:29
  • Thank you for all of your help. I have just cleaned up my code and I can change the font (even though the size does not change, only the size of the screen) – Pseudonym Enigma Feb 06 '15 at 04:34
  • I just kept messing around with and then restarting the code. I finally works. Unfortunately I do not have enough reputation to upvote your answer. Rinzler, thank you for all of your help. – Pseudonym Enigma Feb 06 '15 at 05:21
1

The problem is how you are specifying the font. You should use a tuple rather than a string. Try this:

font = (fontname, size)
textPad.config(
    ...,
    font=font,
    ...
)

A good place for tkinter documentation is effbot.org. On the page about widget styling it says this about specifying the font:

Note that if the family name contains spaces, you must use the tuple syntax described above.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685