python tkinter frame inside a frame

I’m new to Python and Tkinter.
I have created my interface but .grid doesn’t seem to do what I want it to.
Instead of having a tidy look in the centre frame, the LANframe is floating in the centre instead of being close to the Quizes.
Also The statistics doesn’t want to fill the remaining cyan space in the Factframe so it looks odd.
How can I neaten this?

The main outlines work fine but when I Try to put 3 additional frames into those 3 main frames, they either overlap each other or they are in random places like show in the photo

 login= Tk()
    screen_width = login.winfo_screenwidth()
    screen_height = login.winfo_screenheight()
    screen = screen_width+"x"+screen_height
    login.title("Logged in as %s"%name)
    global min_w, max_w, cur_width, expanded
    min_w = 150 # Minimum width of the frame
    max_w = 300 # Maximum width of the frame
    cur_width = min_w # Increasing width of the frame
    expanded = False # Check if it is completely exanded
    # Define the icons to be shown
    global exits, settings, feed, profile
    exits = PhotoImage(file='icons/exits.png') # Make sure the image size is comparable to the minimum frame width
    settings = PhotoImage(file='icons/settings.png')
    feed = PhotoImage(file='icons/feed.png')
    profile = PhotoImage(file='icons/profile.png')
    login.update() # For the width to get updated
    global width1
    width1 = (int(screen_width)-200)
    global frame
    login.grid_rowconfigure(1, weight=1)
    login.grid_columnconfigure(0, weight=1)
    frame = Frame(login,bg=barcolour,width=120,height=login.winfo_height())
    global frame1
    frame1 = Frame(login,bg="blue",width=width1,height=login.winfo_height())
    frame1.grid(row=0,column=5, sticky = "e")
    frame1.grid_rowconfigure(0, weight=1)
    frame1.grid_columnconfigure(1, weight=1)
    width2 = (width1/3)
    global friendframe
    friendframe = Frame(frame1,bg="blue",width=width2,height=login.winfo_height())
    centreframe = Frame(frame1,bg="red",width=width2,height=login.winfo_height())
    centreframe.grid_rowconfigure(1, weight=1)
    centreframe.grid_columnconfigure(0, weight=1)
    factframe= Frame(frame1,bg="cyan",width=width2,height=login.winfo_height())
    timeframe = Frame(centreframe)
    timeframe.grid(row=0,sticky="n", padx=3,pady=3,columnspan=3)
    global clocklabel
    clocklabel =  Label(timeframe,bg =backgrounde,font="Ariel 40")
    quizheight= round(int(login.winfo_height())/4)
    quizgoto= partial(gotoquizinterface)
    quizicons = PhotoImage(file='icons/quizicon.png')
    quizbutton = Button(centreframe,bg="green",image=quizicons,text="  n  Quizes",compound="left",font="Ariel 40",command=quizgoto)
    LanFrame= Frame(centreframe,height=quizheight)
    Langameplayicon= PhotoImage(file='icons/LANgameplay.png')
    LANLobby = partial(LANGameplay, name)
    recentachieve = "Under construction"
    LANButton = Button(LanFrame,image =Langameplayicon, bg="yellow", text="   n LAN Gameplay n Under Construction",compound="left",font="Ariel 30",command=LANLobby)
    Achievements = partial(achievementsgained, name)
    AchievementsButton = Button(factframe,image =Achievementsicon, bg="purple", text=("   n Achievements n Recent Achievements: n"+recentachieve+"n"),compound="left",font="Ariel 30",command=Achievements)
    Statsicon = PhotoImage(file='icons/Statistics.png')
    statsframe = Frame(factframe,bg="pink",height=login.winfo_height())
    Showstats = partial(statshownow, name)
    timeon = "0"
    quizdone = "0"
    Avgscore = "0"
    statsbuttons= Button(statsframe, image =Statsicon, text =(" Stats: n Time spent on:"+timeon+"n Quizes Done:"+quizdone+"n Average Score:"+Avgscore+"n"),compound="left",font="Ariel 20",command=Showstats)
    global profile_b, exits_b, set_b, feed_b
    profilelabel = Label(frame,text='    ',bg=barcolour).grid(row=0,column=1)
    exitslabel = Label(frame,text='    ',bg=barcolour).grid(row=1,column=1)
    setlabel = Label(frame,text='    ',bg=barcolour).grid(row=2,column=1)
    feedlabel = Label(frame,text='    ',bg=barcolour).grid(row=3,column=1)
    profile_b = Label(frame,text='   ',image=profile,compound="right",bg=barcolour,relief=RIDGE)
    exits_b = Button(frame,text='   ',image=exits,compound="right",bg=barcolour,relief=RAISED)
    global set_b
    set_b =  Button(frame,text='   ',image=settings,compound="right",bg=barcolour,relief=GROOVE)
    feed_b = Button(frame,text='   ',image=feed,compound="right",bg=barcolour,relief=SUNKEN)
    profile_b.grid(row=0,column=3,pady=10, columnspan=2)
    exits_b.grid(row=1,column=3,pady=10, columnspan=2)
    set_b.grid(row=2,column=3,pady=50, columnspan=2)
    feed_b.grid(row=3,column=3, columnspan=2)
    frame.bind('<Enter>',lambda e: expand())
    frame.bind('<Leave>',lambda e: contract())

[Unwanted Result] [1]:


Try this:

import tkinter as tk

root = tk.Tk()

# Create the left frame
left_frame = tk.Frame(root, bg="blue")
left_frame.pack(side="left", fill="both", expand=True)

# Create the center frame
center_frame = tk.Frame(root, bg="red")
center_frame.pack(side="left", fill="both", expand=True)
# Populate the center frame
time_frame = tk.Frame(center_frame, bg="white")
time_frame.pack(side="top", fill="x")
# Show the time+date
time_label = tk.Label(time_frame, text="20:44:22", bg="white")
time_label.pack(side="top", fill="x")
date_label = tk.Label(time_frame, text="17/4/2021", bg="white")
date_label.pack(side="top", fill="x")
# Show the `Quizes` button
quizes_frame = tk.Frame(center_frame, bg="green")
quizes_frame.pack(side="top", fill="x")
# Show the image on the left and the label on the right
quizes_img = tk.Label(quizes_frame, bg="green", image=None)
quizes_img.pack(side="top", fill="x", expand=True)
quizes_label = tk.Label(quizes_frame, text="Quizes", bg="green")
quizes_label.pack(side="top", fill="x", expand=True)
# Show the `Lan` button
lan_frame = tk.Frame(center_frame, bg="yellow", height=100) # Dummy height
lan_frame.pack(side="top", fill="x")

# Create the right frame
right_frame = tk.Frame(root, bg="pink")
right_frame.pack(side="left", fill="both", expand=True)

I rewrote part of your code and used .pack because most of the time it’s either side="top" or side="right".

This is how .pack works:

  • You can specify a direction and it will be placed in that direction according to the last created widget. Imagine this case:
|          |
| widget 1 |
|          |

If you call <widget 2>.pack(side="right") then the new widget will go to the right of the last one placed (widget 1) like this:

 ---------- ----------
|          |          |
| widget 1 | widget 2 |
|          |          |
 ---------- ----------