user7823241
user7823241

Reputation: 240

Nesting grids and frames in tkinter and python

I'm trying to set up a grid inside of a frame which is in a larger grid structure. I've tried to distill it to the simplest version of the problem.

from tkinter import Tk, Frame, Label, Entry

root = Tk()
root.geometry('800x800')


frame1 = Frame(root, width=400, height=400, background="Blue")
frame2 = Frame(root, width=400, height=400, background="Red")

frame1.grid(row=0, column=0)
frame2.grid(row=1, column=1)

label1 = Label(frame1,text='Label1')
label1.grid()

Instead of placing the label inside of frame1, the label replaces the frame in the overall grid:

Sample output

I've looked at other examples, but I haven't been able to identify why they work and mine does not.

Upvotes: 2

Views: 11296

Answers (2)

user7823241
user7823241

Reputation: 240

Using jasonharper's observation that the Frame was automatically resizing itself and a similar question posted here, I was able to update the code.

from tkinter import Tk, Frame, Label

root = Tk()
root.geometry('800x800')

root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(1, weight=1)
root.grid_columnconfigure(1, weight=1)

frame1 = Frame(root, background="Blue")
frame2 = Frame(root, background="Red")

frame1.grid(row=0, column=0, sticky="nsew")
frame2.grid(row=1, column=1, sticky="nsew")


label1 = Label(frame1,text='Label1')
label1.grid()

The changes that I made to the code are:

  • I removed the height and width parameters from the Frame instances because they weren't doing anything anyway.
  • Added weighting to the rows and columns of root, the container for the frames, to equally space the frames in the available space
  • Add the 'sticky' parameter to the grid placements of the frames so that the frames would take up all of the space that they were allotted.

The result:

New result

Upvotes: 4

jasonharper
jasonharper

Reputation: 9622

The width= and height= of a Frame normally only apply when it has no children. Once child widgets are added, it resizes itself to fit its contents. So frame1 is still there, it's just now exactly the same size as, and entirely covered by, the label.

To turn off this auto-resizing behavior, call .grid_propagate(0) on the Frame (or .pack_propagate(0), depending on the geometry manager being used for the Frame's children).

Upvotes: 3

Related Questions