Tkinter (basic) help please

[This post looks for help with Tkinter. Can someone please indicate where I should post it as I have not found an appropriate tag for it]

Hello

Average-skilled amateur programmer (Python, C, C++, Java), I decided to embark on an exploration of Tkinter as a means to implement my next GUIs.

[Environment : MacBook Pro M2, macOS 14.2.1, Python 3.12.3]

After reading a few pages of the (excellent) tutorial I was eager to experiment a number of very basic things just to check that my understanding was heading in the right direction.

No luck ! It’s been 2 days that I have been trying to jump over a first hurdle and I would need some help to try and figure out what I am doing wrong.

For my first experiment, the layout I am trying to put together is something like this :

The code I wrote :

from tkinter import *
from tkinter import ttk

root = Tk()
root.title("Tkinter (ttk) experiments – with .grid as geometry manager")
root.geometry('700x600+300+300') # width x height + screen offset
root.config(bg="skyblue")

topFrameStyle = ttk.Style()
topFrameStyle.configure('tfs.TFrame',background='green')
topFrame = ttk.Frame(root, width=680, height=190,style='tfs.TFrame')
topFrame.grid(row=0, column=0, padx=10, pady=5)
# Oops ! topFrame appearance is (default) grey not green. Checking …
print(topFrameStyle.lookup('tfs.TFrame','background')) # green

bottomFrameStyle = ttk.Style()
bottomFrameStyle.configure('bfs.TFrame', background='red')
bottomFrame = ttk.Frame(root, width=680, height=190, style='bfs.TFrame')
bottomFrame.grid(row=1, column=0, padx=10, pady=5)
# Oops ! bottomFrame appearance is (default) grey not red. Checking …
print(bottomFrameStyle.lookup('bfs.TFrame','background')) # red
 
#ttk.Label(topFrame, text="A label in top frame").grid(row=0, column=0, sticky = (N, W))

#ttk.Label(bottomFrame, text="A label in bottom frame").grid(row=0, column=0, sticky = (S, E))

root.mainloop()

With this code I get 2 frames on the main window ok, but they appear in grey (default, I suppose) not red and green. Why ?

Note that the Labels bit is commented out.

If I uncomment the first Label the top frame disappears alltogether and looks like it is replaced with the Label (which is not placed according to ‘sticky=(N,W)’).

And if uncomment the second Label all frames disappear and the Labels appear but at totally unexpected places.

It is plain clear that I am doing something severely wrong. Could someone give me a hand to try and put me back in the right track ?

Many thanks in advance.

The frames did not disappear. Rather you filled them completely with one widget with no padding. The frames were then shrunk to the minimum size needed. Add , padx=20, pady=20 to each label.

If you don’t get tkinter questions answered here, try stackoverflow.com where there are hundred of existing tkinter answers to search and active (last I knew) tkinter experts.

Note: a single widget in a frame is, in a sense, nonsensical, as the purpose of a frame is to treat multiple widgets as a single unit. To really experiment with gridding (or packing, but learning .grid is a great idea) you need multiple widgets.

Many thanks. That makes sense and I seem to have some new avenue to explore.

Meanwhile I have added an additional label to each frame

from tkinter import *
from tkinter import ttk


root = Tk()
root.title("Tkinter (ttk) experiments – with .grid as geometry manager")
root.geometry('700x600+300+300') # width x height + screen offset
root.config(bg="skyblue")

topFrameStyle = ttk.Style()
topFrameStyle.configure('tfs.TFrame',background='green')
topFrame = ttk.Frame(root, width=680, height=190,style='tfs.TFrame')
topFrame.grid(row=0, column=0, padx=10, pady=5)
# Oops ! topFrame appearance is (default) grey not green. Checking …
print(topFrameStyle.lookup('tfs.TFrame','background')) # green

bottomFrameStyle = ttk.Style()
bottomFrameStyle.configure('bfs.TFrame', background='red')
bottomFrame = ttk.Frame(root, width=680, height=190, style='bfs.TFrame')
bottomFrame.grid(row=1, column=0, padx=10, pady=5)
# Oops ! bottomFrame appearance is (default) grey not red. Checking …
print(bottomFrameStyle.lookup('bfs.TFrame','background')) # red
 
ttk.Label (topFrame, text="A label in top frame").grid(row=0, column=0, padx = 20, pady = 20, sticky = (N, W))
ttk.Label (topFrame, text="Another label in top frame").grid(row=1, column=0, padx = 20, pady = 20, sticky = (N, W))

ttk.Label(bottomFrame, text="A label in bottom frame").grid(row=0, column=0, padx=20, pady=20, sticky = (S, E))
ttk.Label(bottomFrame, text="Another label in bottom frame").grid(row=1, column=0, padx=20, pady=20, sticky = (S, E))


root.mainloop()

I get this

The labels do appear at their intended places.
Why the frames are still not in the colour I have specified in their associated ‘Styles’ and why they shrank is something I have to work on at the next iteration of my trials.

Many thanks again.

I got it to work using the pack layout:

import tkinter as tk
import tkinter.ttk as ttk

root = tk.Tk()
root.title("Tkinter (ttk) experiments – with .grid as geometry manager")
root.geometry('700x600+300+300') # width x height + screen offset
root.config(bg="skyblue")

topFrameStyle = ttk.Style()
topFrameStyle.configure('tfs.TFrame',background='green')
topFrame = ttk.Frame(root, width=680, height=190,style='tfs.TFrame')
topFrame.grid(row=0, column=0, padx=10, pady=5)

topFrame.pack_propagate(False)

bottomFrameStyle = ttk.Style()
bottomFrameStyle.configure('bfs.TFrame', background='red')
bottomFrame = ttk.Frame(root, width=680, height=190, style='bfs.TFrame')
bottomFrame.grid(row=1, column=0, padx=10, pady=5)

bottomFrame.pack_propagate(False)

ttk.Label(topFrame, text="A label in top frame", background='green').pack(side=tk.TOP, anchor=tk.W)

ttk.Label(bottomFrame, text="A label in bottom frame", background='red').pack(side=tk.BOTTOM, anchor=tk.E)

root.mainloop()

Brilliant, it works ! Thanks.

I’m still left with issue that the frames are grey, not green and red as specified in their associated ‘style’. Something I still have to sort out.

Apart from that, given the strong sales pitch that the tutorial makes for the use of .grid as the preferred geometry manager ( TkDocs Tutorial - Tk Concepts ), the fact that the solution relies on pack is a bit disappointing (my intention was to use only .grid). The tutorial also says (same page) that once a ‘master’ widget uses .grid all ‘slave’ widgets must also use .grid. Your solution shows that that statement has to somehow be qualified : the Labels are ‘slaves’ of the Frames and while the Frames use .grid the Labels are happy using pack.

Again thanks for the contribution.

On the issue of Frames appearing always in grey:

Tkinter Frames: background option makes them appear the specified colour
ttk Frames: have a different interpretation of the background option

The following code will display a green Frame

from tkinter import *

root = Tk()
root.title("Main Window")
root.geometry('700x400+300+300') # width x height + screen border distance
root.config(bg="skyblue")

aFrame = Frame(root, width=680, height=190,background='green')
aFrame.grid(row=0, column=0, padx=10, pady=5)
#Will display a green Frame

root.mainloop()

The following code will display a grey Frame with a green border

from tkinter import *
from tkinter import ttk

root = Tk()
root.title("Main Window")
root.geometry('700x400+300+300') # width x height + screen border distance
root.config(bg="skyblue")

aFrameStyle = ttk.Style()
aFrameStyle.configure('tfs.TFrame',background='green',relief='sunken',borderwidth=5)
aFrame = ttk.Frame(root, width=680, height=190,style='tfs.TFrame')
aFrame.grid(row=0, column=0, padx=10, pady=5)
#Will display a grey Frame with a green border

root.mainloop()

Cheers