I am writing a quiz app in Python using Tkinter, which has an options screen (number of questions, subjects, etc) followed by a questions screen. I have implemented this using tkraise() to switch between frames. All was working well until I decided to put an image as the background.
I am new to Python so I wrote a simple test to try to see what I was doing wrong. I gave the various frames different background colours and left a gap round the edge with padding so that I could see what was going on. With all the frames created in the main body of code, everything worked as I thought it should, but when I used a class derived from ttk.Frame the background became grey (not even the colour of the frame I had specified using Style) with no image.
Here is the code with no use of classes that gives almost the output I expected - a thin yellow rectangle from mainframe surrounding the background from my .png file with 2 buttons in a red rectangle in the centre. I did expect a thin blue rectangle just inside the yellow one from subframe, but I am guessing that the overlarge .png file has had preference over the padding - is this correct?
from tkinter import *
from tkinter import ttk
def dummy():
pass
root = Tk()
root.geometry("1000x600")
root.title("Testing Frames")
s = ttk.Style()
s.configure('Frame1.TFrame', background='yellow')
s.configure('Frame2.TFrame', background='blue')
s.configure('Frame3.TFrame', background='red')
mainframe = ttk.Frame(root, style = 'Frame1.TFrame', padding="5 5 5 5")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
subframe = ttk.Frame(mainframe, style = 'Frame2.TFrame', padding="5 5 5 5")
img = PhotoImage(file = "resources/QuestionMarks.png")
label = Label(subframe, image = img)
label.place(anchor = CENTER, relx = 0.5, rely = 0.5)
subframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)
subframe2 = ttk.Frame(subframe, style = 'Frame3.TFrame', padding="5 5 5 5")
subframe2.place(anchor = CENTER, relx = 0.5, rely = 0.5)
button = ttk.Button(subframe2, text = "Button 1", command=dummy)
button.grid(row = 0, column = 0)
button2 = ttk.Button(subframe2, text = "Button 2", command=dummy)
button2.grid(row = 0, column = 1)
for child in subframe2.winfo_children():
child.grid_configure(padx=5, pady=5)
root.mainloop()
Here is the code where I have derived a class from ttk.Frame for my mainframe. This no longer shows the background from the png file. Instead the area is grey.
from tkinter import *
from tkinter import ttk
def dummy():
pass
class Mainframe(ttk.Frame):
def __init__(self,parent):
super().__init__(parent)
s = ttk.Style()
s.configure('Frame1.TFrame', background='yellow')
s.configure('Frame2.TFrame', background='blue')
s.configure('Frame3.TFrame', background='red')
self.columnconfigure(0, weight=1)
self.rowconfigure(0, weight=1)
self['padding'] = '5 5 5 5'
self['style'] = 'Frame1.TFrame'
subframe = ttk.Frame(self, style = 'Frame2.TFrame', padding="5 5 5 5")
img = PhotoImage(file = "resources/QuestionMarks.png")
label = Label(subframe, image = img)
label.place(anchor = CENTER, relx = 0.5, rely = 0.5)
subframe2 = ttk.Frame(subframe, style = 'Frame3.TFrame', padding="5 5 5 5")
button = ttk.Button(subframe2, text = "Button 1", command=dummy)
button.grid(row = 0, column = 0)
button2 = ttk.Button(subframe2, text = "Button 2", command=dummy)
button2.grid(row = 0, column = 1)
for child in subframe2.winfo_children():
child.grid_configure(padx=5, pady=5)
subframe2.place(anchor = CENTER, relx = 0.5, rely = 0.5)
subframe.grid(column=0, row=0, sticky=(N, W, E, S))
root = Tk()
root.geometry("1000x600")
root.title("Testing Frames")
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
mainframe = Mainframe(root)
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
root.mainloop()
My png file is slightly larger than my 1000 x 600 frame, but using a smaller png file will still show the problem so long as it is larger than the 2 buttons and their frame. I am using Ubuntu 20.04, Python 3.8.10 and Tk 8.6.10
What is going on here? Obviously I want to leave the classes in my quiz app, but how can I get the background I would like?