Fake
Fake

Reputation: 3

Why won't my frame pack python3 tkinter

When I run the code below I do not get an error but the bottom frame doesn't appear in the window please can you tell me why and how I can make it appear (using the pack method NOT GRID please). I am using Python 3.5.0

import tkinter 
from tkinter import *
root = tkinter.Tk()
root.geometry("1920x1080")
TopFrame = Frame(root, width=1920, height=200, bg= "green")
TopFrame.pack(side=TOP)
MiddleRightFrame = Frame(root, width=1120, height=730, bg="orange")
MiddleRightFrame.pack(side=RIGHT)
MiddleLeftFrame = Frame(root, width=800, height=730, bg="black")
MiddleLeftFrame.pack(side=LEFT)
BottomFrame = Frame(root, width=1920, height=150, bg="blue")
BottomFrame.pack(side=BOTTOM)

Upvotes: 0

Views: 969

Answers (3)

Bryan Oakley
Bryan Oakley

Reputation: 386362

Your MiddleLeftFrame is 800 pixels wide. Your MiddleRightFrame is 1120 pixels. 1120 + 800 = 1920. You're forcing the window to be only 1920 pixels wide, so there's no room for the blue frame.

Remove this line and your frame will appear: root.geometry("1920x1080")

If your intent is for it to appear at the bottom of the window, spanning the entire width of the window, then call pack on it before you call pack on the left and right sides.

Also, I strongly recommend grouping your pack statements together. It makes the code easier to manage in my experience (and I have a lot of experience!).

import tkinter 
from tkinter import *
root = tkinter.Tk()
root.geometry("1920x1080")

TopFrame = Frame(root, width=1920, height=200, bg= "green")
MiddleRightFrame = Frame(root, width=1120, height=730, bg="orange")
MiddleLeftFrame = Frame(root, width=800, height=730, bg="black")
BottomFrame = Frame(root, width=1920, height=150, bg="blue")

TopFrame.pack(side=TOP)
BottomFrame.pack(side=BOTTOM)
MiddleRightFrame.pack(side=RIGHT)
MiddleLeftFrame.pack(side=LEFT)

root.mainloop()

The reason this works is due to the packer algorithm. When you place something on the left or right, it will allocate all of the remaining vertical space on that side. Thus, after you pack something on the left and right and then later pack something on the bottom, the "bottom" is the bottom of the space between the left and right, not the bottom of the window as a whole.

Here is the canonical description of how pack works:

http://tcl.tk/man/tcl8.5/TkCmd/pack.htm#M26

Upvotes: 1

Nae
Nae

Reputation: 15355

Add:

tkinter.mainloop()

so that the GUI starts waiting for events as opposed to skipping to close itself.


Additionally, pack uses a filling algorithm which calculates dynamically to fill the empty space. You shouldn't really be doing it like this but a simple call swap would suffice in this specific case. Call:

BottomFrame.pack(side=BOTTOM)

exactly after TopFrame's pack:

TopFrame.pack(side=TOP)
BottomFrame.pack(side=BOTTOM)
MiddleRightFrame.pack(side=RIGHT)
MiddleLeftFrame.pack(side=LEFT)

Upvotes: 0

Crawley
Crawley

Reputation: 640

I think the issue is that you are using pack sides so that in the middle there is a line of nothing. One way to get around this is to create a MiddleFrame where pack sides are used and then just pack the other frames.

import tkinter 
from tkinter import *

root = tkinter.Tk()
root.geometry("1920x1080")

TopFrame = Frame(root, width=1920, height=200, bg= "green")
TopFrame.pack()

#the middle frame
MiddleFrame = Frame(root)

#pack the two middle frames into the frame created above
#the parent of the two middle frames change to become MiddleFrame instead of root
MiddleRightFrame = Frame(MiddleFrame, width=1120, height=730, bg="orange")
MiddleRightFrame.pack(side=RIGHT)

MiddleLeftFrame = Frame(MiddleFrame, width=800, height=730, bg="black")
MiddleLeftFrame.pack(side=RIGHT)

#pack the middle frame with both frames inside it
MiddleFrame.pack()

BottomFrame = Frame(root, width=1920, height=150, bg="blue")
BottomFrame.pack()

Upvotes: 0

Related Questions