1

I am creating a simple application in python using tkinter, which includes a menu from which I can pick different options and move to new menus. I am using the answer given by Steven Vascellaro here to destroy the frames as I move between them. In an earlier test version of the program I was able to give the buttons my custom font and have it display correctly, but when I add the master, which switches between the different frames, the font no longer works, only making the text on the buttons slightly larger.

The version of the code that works correctly is this:

import tkinter as tk
from tkinter.font import Font, nametofont
class MainMenu(tk.Frame):              
def __init__(self, master=None):
    tk.Frame.__init__(self, master)   
    self.grid()                       
    self.createWidgets()

def createWidgets(self):
    global myFont
    top=self.winfo_toplevel()                
    top.rowconfigure(0, weight=1)            
    top.columnconfigure(0, weight=1)         
    self.rowconfigure(0, weight=1, pad=50)           
    self.columnconfigure(0, weight=1)        
    self.resume = tk.Button(self, text='Continue', height=2, width=10, font=myFont,  command=self.quit)
    self.library = tk.Button(self, text='Library', height=2, width=10,   command=self.quit)
    self.resume.grid(row=1, column=0,sticky=tk.N+tk.E+tk.W)
    self.library.grid(row=3, column=0,sticky=tk.E+tk.W) 

root = tk.Tk()
global myFont
fontCheck = open("Options.txt","r")
for line in fontCheck:
    if "Font" in line:
        tempLine = line.strip()
        fontDetails = tempLine.split(",")
        print(fontDetails)
myFont = Font(family=fontDetails[1], size=int(fontDetails[2]), weight="bold")
app = MainMenu()
app.mainloop()          
root.destroy()     `

Producing a menu that looks like this

But when I add this master section it no longer works:

import tkinter as tk
from tkinter.font import Font, nametofont

class Application(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self._frame = None
        self.switch_frame(MainMenu)

    def switch_frame(self, frame_class):
        new_frame = frame_class(self)
        if self._frame is not None:
            self._frame.destroy()
        self._frame = new_frame
        self._frame.grid()

class MainMenu(tk.Frame):              
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)   
        self.grid()                       
        self.createWidgets()

    def createWidgets(self):
        global myFont
        top=self.winfo_toplevel()                
        top.rowconfigure(0, weight=1)            
        top.columnconfigure(0, weight=1)         
        self.rowconfigure(0, weight=1, pad=50)           
        self.columnconfigure(0, weight=1)        
        self.resume = tk.Button(self, text='Continue', height=2, width=10, font=myFont,  command=self.quit)
        self.library = tk.Button(self, text='Library', height=2, width=10,   command=self.quit)
        self.resume.grid(row=1, column=0,sticky=tk.N+tk.E+tk.W)
        self.library.grid(row=3, column=0,sticky=tk.E+tk.W) 

root = tk.Tk()
global myFont
fontCheck = open("Options.txt","r")
for line in fontCheck:
    if "Font" in line:
        tempLine = line.strip()
        fontDetails = tempLine.split(",")
        print(fontDetails)
myFont = Font(family=fontDetails[1], size=int(fontDetails[2]), weight="bold")
app = Application()
app.mainloop()          
root.destroy()  

It creates a menu that looks like this

I would love if someone could explain why the font is not working correctly across the frames and explain how I can fix this issue.

Kiwi
  • 13
  • 4
  • 1
    Please create a [mcve] that illustrates the problem. – Bryan Oakley May 18 '18 at 17:38
  • I've made the second example more complete, so it's exactly what I have in my file right now. It seems to follow the rules as described but if there's anything more I can add I would be happy to. – Kiwi May 18 '18 at 17:54

1 Answers1

1

You're creating 2 instances of tk.Tk: One where you set up the font, and one for your application. These two instances don't share the font. The solution would be to set up the Font inside your Application class (as a method, probably, and at initialization most likely).

class Application(tk.Tk):
    def __init__(self, *args, fontfile = None, **kw):
        super().__init__(*args, **kw)
        if fontfile is None: fontfile = "Options.txt"

        self._frame = None
        self.fontfile = fontfile
        self.setupFont()
        self.switch_frame(MainMenu)

    def setupFont(self):
        global myFont
        with open(self.fontfile,"r")
        for line in fontCheck:
            if "Font" in line:
                tempLine = line.strip()
                fontDetails = tempLine.split(",")
                print(fontDetails)
        myFont = Font(family=fontDetails[1], size=int(fontDetails[2]), weight="bold")

A few other Notes:

  • I don't particularly like the use of global; either having it as an attribute of Application or as a ttk.Style would be preferable (in my opinion).
  • You may want to consider using a options file with a predefined structure (recommend json) that can be read from in a more explicit fashion.
Reid Ballard
  • 1,480
  • 14
  • 19
  • Thanks for the answer, it's working perfectly now. Thanks for the tips too, I'll keep them in mind. – Kiwi May 18 '18 at 18:40