title: tkinter sticky not working for some frames
body: <p>I'm using tkinter to write a card game, and I'm having trouble with he grid layout manager 'sticky' configuration. I would like help fixing my code to make the frames display in the desired location. In my code and illustration below, there is a frame (b2) that contains two other (one green, b2a; and one red; b2b) frames. I would like to display frame b2 at the bottom of the parent frame (frame b). I've tried various combinations of N+S+E+W as arguments for 'sticky', for both frame b2 and the child frames b2a and b2b. However, I've been unable to make frame b2 (and more importantly b2a and b2b) appear in the desired location (the bottom image below with the correct placement was made in Illustrator).</p>
  
  <p>In particular, it seems that sticky arguments in lines 27, 36 and 37 have no effect on the placement of frame b2, b2a and b2b inside of frame b.</p>
  
  <pre><code>from tkinter import *
  from PIL import Image, ImageTk
  
  def main(root):
      cons = Frame(root)
      cons.grid()
  
      frameDict = setup_frames(cons)
      populate_frames(frameDict)
  
  def setup_frames(cons):
      frame = {}
      # Parental Frames
      frame['a'] = Frame(cons, borderwidth=2, relief='groove')
      frame['b'] = Frame(cons, borderwidth=2, relief='groove')
      frame['c'] = Frame(cons, borderwidth=2, relief='groove')
  
      frame['a'].grid(row=0, column=0, sticky=N+S+E+W)
      frame['b'].grid(row=0, column=1, sticky=N+S+E+W)
      frame['c'].grid(row=1, column=0, columnspan=2)
  
      # Progeny 0 Frames:
      frame['b1'] = Frame(frame['b'], borderwidth=2, relief='groove')
      frame['b2'] = Frame(frame['b'], borderwidth=2, relief='groove')
  
      frame['b1'].grid(row=0, column=0, sticky=N+S+E+W)
      frame['b2'].grid(row=1, column=0, sticky=N+S+E+W)
  
      # Progeny 1 Frames:
  
      frame['b2a'] = Frame(frame['b2'], borderwidth=2, relief='groove',
                           background='green')
      frame['b2b'] = Frame(frame['b2'], borderwidth=2, relief='groove',
                           background='red')
  
      frame['b2a'].grid(row=0, column=0, sticky=S)
      frame['b2b'].grid(row=0, column=1, sticky=SW)
  
      return frame
  
  def populate_frames(fr):
  
      # Populating 'a' frame
      aLab = Label(fr['a'], image=img[0])
      aLab.grid()
  
      # Populating b2a &amp; b2b frames
      bLab = Label(fr['b2a'], image=img[1])
      bLab.grid(row=0, column=0)
  
      bLab = Label(fr['b2b'], image=img[2])
      bLab.grid(row=0, column=1)
  
      # Populating c1 frame
      cLab = Label(fr['c'], image=img[3])
      cLab.grid()
  
  if __name__ == '__main__':
      root = Tk()
      img = []
      w = [40,  160, 80, 480]
      h = [180, 60,  60, 60]
      for i in range(4):
          a = Image.new('RGBA', (w[i], h[i]))
          b = ImageTk.PhotoImage(a)
          img.append(b)
      main(root)
  </code></pre>
  
  <p>The images below illustrate where the offending frames (green and red) are displaying (top) and where I would like them displayed (bottom).</p>
  
  <p>Could someone please help me display frame b2 (and ultimately b2a and b2b) in the correct position (Edit: at the bottom of frame b, and spanning from the right side of frame a to the right side of frame c)?</p>
  
  <p><a href="https://i.stack.imgur.com/x6ZXF.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/x6ZXF.png" alt="illustration of incorrect and correct frame placement"></a></p>
  
  <p>Update:
  I've solved both problems (vertical placement and horizontal justification of frame b2) using grid weights, as Bryan suggested. The solution to the vertical placement problem is straightforward, but I would not have predicted the solution to the horizontal justification issue.</p>
  
  <p>I solved the vertical placement problem by giving weight=1 to row 0 in frame b (resulting in the upper panel of the figure below).</p>
  
  <p>I solved the horizontal justification problem (wherein frames b1 and b2 were not stretching to fill frame b) by assigning weight=1 to column 0 in frame b. The frame outlines in the figure below show that frame b is already stretched from the right side of frame a to the right side of frame c. It's strange to me that giving weight to the only column in a frame would be required to allow child frames to fill horizontally. In any case, I've pasted my working code below. Lines 40 and 41 solved the issue I was having.</p>
  
  <pre><code>from tkinter import *
  from PIL import Image, ImageTk
  
  def main(root):
      cons = Frame(root)
      cons.grid()
  
      frameDict = setup_frames(cons)
      populate_frames(frameDict)
  
  def setup_frames(cons):
      frame = {}
      # Parental Frames
      frame['a'] = Frame(cons, borderwidth=2, relief='groove')
      frame['b'] = Frame(cons, borderwidth=2, relief='groove')
      frame['c'] = Frame(cons, borderwidth=2, relief='groove')
  
      frame['a'].grid(row=0, column=0, sticky=N+S+E+W)
      frame['b'].grid(row=0, column=1, sticky=N+S+E+W)
      frame['c'].grid(row=1, column=0, columnspan=2)
  
      # Progeny 0 Frames:
      frame['b1'] = Frame(frame['b'], borderwidth=2, relief='groove')
      frame['b2'] = Frame(frame['b'], borderwidth=2, relief='groove')
  
      frame['b1'].grid(row=0, column=0, sticky=N+S+E+W)
      frame['b2'].grid(row=1, column=0, sticky=N+S+E+W)
  
      # Progeny 1 Frames:
  
      frame['b2a'] = Frame(frame['b2'], borderwidth=2, relief='groove',
                           background='green')
      frame['b2b'] = Frame(frame['b2'], borderwidth=2, relief='groove',
                           background='red')
  
      frame['b2a'].grid(row=0, column=0, sticky=S)
      frame['b2b'].grid(row=0, column=1, sticky=SW)
  
      # Weighting
      frame['b'].grid_rowconfigure(0, weight=1)
      frame['b'].grid_columnconfigure(0, weight=1)
  
      return frame
  
  def populate_frames(fr):
  
      # Populating 'a' frame
      aLab = Label(fr['a'], image=img[0])
      aLab.grid()
  
      # Populating b2a &amp; b2b frames
      bLab = Label(fr['b2a'], image=img[1])
      bLab.grid(row=0, column=0)
  
      bLab = Label(fr['b2b'], image=img[2])
      bLab.grid(row=0, column=1)
  
      # Populating c1 frame
      cLab = Label(fr['c'], image=img[3])
      cLab.grid()
  
  if __name__ == '__main__':
      root = Tk()
      img = []
      w = [40,  160, 80, 480]
      h = [180, 60,  60, 60]
      for i in range(4):
          a = Image.new('RGBA', (w[i], h[i]))
          b = ImageTk.PhotoImage(a)
          img.append(b)
      main(root)
  </code></pre>
  
  <p>Consistent with Bryan's advice, it does seem to be a good rule of thumb to assign a weight to at least one column and one row in every container.</p>
  
  <p>Here's before and after I fixed the horizontal justification problem:</p>
  
  <p><a href="https://i.stack.imgur.com/TzCoH.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/TzCoH.png" alt="before and after horizontal justification"></a></p>
  
  <p>Using Python 3.4, Yosemite</p>