-1

First post here, I'm working on a very basic text editor as a beginner project in python and I've managed to get a big chunk of it working, but I just can't figure out how to make the font and font sizing menu buttons work. At first, I just had one button that switched the text to Times New Roman with a size of 12 instead of the default Tkinter font, and that worked, but when I added in the capability to change the font and font size independently it would just default to Calibri size 12 (which are both the last buttons added in the code), and I couldn't change the font or sizing. Any ideas?

Problem Code:

def change_font(fontname):
    global font
    font = fontname
    text_info.configure(font=(font, font_size))

def change_font_size(size):
    global font_size
    font_size = size
    text_info.configure(font=(font, font_size))

font_menu = Menu(menubar, tearoff=0)
font_menu.add_command(label="Times New Roman", command=change_font("Times New Roman"))
font_menu.add_command(label="Calibri", command=change_font("Calibri"))
menubar.add_cascade(label="Font", menu=font_menu)

font_size_menu = Menu(menubar, tearoff=0)
for i in range(8, 13):
    font_size_menu.add_command(label=str(i), command=change_font_size(i))
menubar.add_cascade(label="Font Size", menu=font_size_menu)

Full Code:

from tkinter import *

def text_opener():
    try:
        f = open(text_name, "r+")
    except FileNotFoundError:
        f = open(text_name, "a+")
        f.close()
        f = open(text_name, "r+")
    return f

text_name = input("What is the name of your .txt file? ") + ".txt"
text = text_opener()
root = Tk()

# intended default font and font size
font = "Arial"
font_size = 11

root.title("Text Editor")
root.geometry("640x360")
root.resizable(width=False, height=False)
scrollbar = Scrollbar(root)
scrollbar.pack(side=RIGHT, fill=Y)
text_info = Text(root, yscrollcommand=scrollbar.set, wrap=WORD)
scrollbar.config(command=text_info.yview)
text_info.pack(fill=BOTH)
text_info.insert(INSERT, text.read())
menubar = Menu(root)
filemenu = Menu(menubar, tearoff=0)

def save():
    text.seek(0)
    text.write(text_info.get("1.0", 'end-1c'))
    text.truncate()

filemenu.add_command(label="Save", command=save)
filemenu.add_separator()
filemenu.add_command(label="Exit", command=root.quit)
menubar.add_cascade(label="File", menu=filemenu)

# problem code below
def change_font(fontname):
    global font
    font = fontname
    text_info.configure(font=(font, font_size))

def change_font_size(size):
    global font_size
    font_size = size
    text_info.configure(font=(font, font_size))

font_menu = Menu(menubar, tearoff=0)
font_menu.add_command(label="Times New Roman", command=change_font("Times New Roman"))
font_menu.add_command(label="Calibri", command=change_font("Calibri"))
menubar.add_cascade(label="Font", menu=font_menu)

font_size_menu = Menu(menubar, tearoff=0)
for i in range(8, 13):
    font_size_menu.add_command(label=str(i), command=change_font_size(i))
menubar.add_cascade(label="Font Size", menu=font_size_menu)

root.config(menu=menubar)
root.lift()
root.attributes('-topmost', True)
root.after_idle(root.attributes, '-topmost', False)
root.mainloop()
text.close()

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
  • Does this answer your question? [tkinter creating buttons in for loop passing command arguments](https://stackoverflow.com/questions/10865116/tkinter-creating-buttons-in-for-loop-passing-command-arguments) – Karl Knechtel Aug 18 '22 at 04:02

1 Answers1

1

To pass an argument into a command you have to use a lambda function or a partial object or similar.

font_menu.add_command(label="Times New Roman", command=lambda: change_font("Times New Roman"))
Novel
  • 13,406
  • 2
  • 25
  • 41
  • I changed this in my code, but now the for loop that I used for adding font size buttons doesn't work. I'm fine with just manually copying and pasting a bunch of font sizes (which I tried and does work), but do you know what the reason for that is? – GianThaMan Jan 10 '21 at 22:36
  • @GianThaMan: see https://stackoverflow.com/q/17677649/7432 – Bryan Oakley Jan 10 '21 at 22:50