1

Using Tkinter i have created 5 frames, each containing

  • frame0 - label,Entry box and a button(Enter)
  • frame1 - label and list box at the left side
  • frame2 - 2 buttons(select & unselect) at the center
  • frame3 - label and listbox at the right side
  • frame4 - 2 buttons(done & clear)

     ----------------------------------------
     |                 frame0               |
     ----------------------------------------
     |            |            |            |
     |  frame1    |   frame2   |  frame3    |
     |            |            |            |
     ----------------------------------------
     |                 frame4               |
     ----------------------------------------
    

This is my code:

from Tkinter import *

def toplevelwin():

    def clear():
        return

    def select():
        return

    def unselect():
        return

    def done():
        return

    def enter():
        return

    window = Toplevel()

    frame0 = Frame(window)
    frame0.grid(row=0, column=0, sticky=W, padx=5, pady=5, columnspan=2)
    frame0.grid_columnconfigure(1,weight=2)
    lblentry = Label(frame0, text="Entery Box:")
    lblentry.grid(row=0, column=0, sticky=W)
    entrybx = Entry(frame0)
    entrybx.grid(row=1,column=0,sticky=N+S+E+W, columnspan=2)
    entrybt = Button(frame0, text=' Enter ', command=enter)
    entrybt.grid(row=1,column=2,sticky=N+W, padx=3)

    frame1 = Frame(window)
    frame1.grid(row=1, column=0, sticky=E+W, padx=5, pady=5)
    lblshow_lst = Label(frame1, text="List Box 1:")
    lblshow_lst.grid(row=0,sticky=W)
    show_lst = Listbox(frame1)
    show_lst.grid(row=1,sticky=W)

    frame2 = Frame(window)
    frame2.grid(row=1, column=1, sticky=W)
    frame2.grid_columnconfigure(1,weight=1)
    selbtn = Button(frame2, text='Select', command=select)
    selbtn.grid(row=0, padx=5, sticky=E+W)
    selbtn.grid_columnconfigure(1,weight=1)
    uselbtn = Button(frame2, text='Unselect', command=unselect)
    uselbtn.grid(row=1, padx=5, sticky=E+W)
    uselbtn.grid_columnconfigure(1,weight=1)

    frame3 = Frame(window)
    frame3.grid(row=1, column=2, sticky=W, padx=5, pady=5)
    lblsel_lst = Label(frame3, text="List Box 2:")
    lblsel_lst.grid(row=0,sticky=W)
    sel_lst = Listbox(frame3)
    sel_lst.grid(row=1, column=0, sticky=W)

    frame4 = Frame(window)
    frame4.grid(row=2, column=0, sticky=E, padx=5, pady=5)
    Button(frame4, text=' Done ', command=done).grid(row=0, column=0, padx=7 ,pady=2)
    Button(frame4, text='Clear', command=clear).grid(row=0,column=1, padx=7,pady=2)
    window.wait_window(window)


root = Tk()
toplevelwin()
root.mainloop()

And this is how my window looks now:

enter image description here

My Question is:

  • How do i expand frame0 uptill frame3. ie, i want the entry box to extend till frame3's end having the button(enter) to its right side as it is.
  • And i want the bottom frame's button(done and clear) to be placed on the right side of the window

Tries:

  • i tried to increase the size of the entry widget, which in turn pushed frame2 and frame3 to the right side.

  • used sticky=N+S+W+E, which pushed it to the center of the window

  • also did tried sticky=W for the bottom frame containing 2 buttons. They moved to the center but not right

arvindh
  • 739
  • 4
  • 12
  • 28
  • Do you really want two windows? – Eric Levieil Jul 24 '15 at 10:17
  • because you're using those frames, you could use `pack` which might make things easier. Are you interested in that solution, or are you specifically asking about how to fix problems with grid? ie: is the question "how do I get the layout I want" or is it "what am I doing wrong with grid"? – Bryan Oakley Jul 24 '15 at 10:23
  • 1
    @EricLevieil,.. it the toplevel window. I havent posted the complete code, its just the frame work of what im developing – arvindh Jul 24 '15 at 11:50
  • @BryanOakley,.. first of all, im sorry if my question wasnt clear. This is just the begining of the toplevel window and i will add some other widgets as required. So i thought going for `grid` would be a better option. And more over i wanted to "how can i get the layout what i wanted" using `grid`. Also if you come across wrong or weird code lines, plz do rectify me – arvindh Jul 24 '15 at 11:56

2 Answers2

4

When using grid, to make a widget capable of expanding or shrinking, you need to set its sticky parameter and set its grid cell's weight. Each column and each row of a grid has a weight.

By default all column and row weights are 0, which mean they will shrink to the smallest valid size.

To make it expand in the east-west direction, increase its column weight with grid_columnconfigure.

To make it expand in the north-south direction, increase its row weight with grid_rowconfigure.


So, for frame0,

  • Use columnspan=3 to make frame0 span 3 columns.
  • Use sticky='WE' to make frame0 stick to both the west and east sides of its cell.
  • Use frame0.grid_columnconfigure(0, weight=1) to increase the grid cell's weight to 1.

For frame4,

frame4 = Frame(window)
frame4.grid(row=2, column=0, sticky='E', padx=5, pady=5, columnspan=3)

would work by making frame4 stick to the east side if its cell. Note that without a weight, frame4 shrinks too; it just shrinks while sticking to the east side, so the buttons it contains end up on the right.

If you want to make frame4 span the entire space from west to east as shown in your diagram, then use

frame4.grid(row=2, column=0, sticky='WE', padx=5, pady=5, columnspan=3)
frame4.grid_columnconfigure(0, weight=1)
Button(frame4, text=' Done ', command=done).grid(
    row=0, column=0, padx=7, pady=2, sticky='E')
Button(frame4, text='Clear', command=clear).grid(
    row=0, column=1, padx=7, pady=2, sticky='E')

enter image description here

from Tkinter import *

def toplevelwin():
    def clear(): return
    select = unselect = done = enter = clear
    window = Toplevel()

    frame0 = Frame(window)
    frame0.grid(row=0, column=0, sticky='WE', padx=5, pady=5, columnspan=3)
    frame0.grid_columnconfigure(0, weight=1)
    lblentry = Label(frame0, text="Entry Box:")
    lblentry.grid(row=0, column=0, sticky='W')
    entrybx = Entry(frame0)
    entrybx.grid(row=1, column=0, sticky='NSEW', columnspan=2)
    entrybt = Button(frame0, text=' Enter ', command=enter)
    entrybt.grid(row=1, column=2, sticky='NW', padx=3)

    frame1 = Frame(window)
    frame1.grid(row=1, column=0, sticky='EW', padx=5, pady=5)
    lblshow_lst = Label(frame1, text="List Box 1:")
    lblshow_lst.grid(row=0, sticky='W')
    show_lst = Listbox(frame1)
    show_lst.grid(row=1, sticky='W')

    frame2 = Frame(window)
    frame2.grid(row=1, column=1, sticky='W')
    selbtn = Button(frame2, text='Select', command=select)
    selbtn.grid(row=0, padx=5, sticky='EW')
    uselbtn = Button(frame2, text='Unselect', command=unselect)
    uselbtn.grid(row=1, padx=5, sticky='EW')

    frame3 = Frame(window)
    frame3.grid(row=1, column=2, sticky='W', padx=5, pady=5)
    lblsel_lst = Label(frame3, text="List Box 2:")
    lblsel_lst.grid(row=0, sticky='W')
    sel_lst = Listbox(frame3)
    sel_lst.grid(row=1, column=0, sticky='W')

    frame4 = Frame(window)
    frame4.grid(row=2, column=0, sticky='WE', padx=5, pady=5, columnspan=3)
    frame4.grid_columnconfigure(0, weight=1)
    Button(frame4, text=' Done ', command=done).grid(
        row=0, column=0, padx=7, pady=2, sticky='E')
    Button(frame4, text='Clear', command=clear).grid(
        row=0, column=1, padx=7, pady=2, sticky='E')

    window.wait_window(window)


root = Tk()
toplevelwin()
root.mainloop()
Community
  • 1
  • 1
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
1

You don't need the frames (except for the buttons at the bottom). Juste make your widgets like that:

entrybx = Entry(window)
entrybx.grid(row=0,column=0,sticky=N+S+E+W, columnspan=2) # columnspan= 3 better?

Use sticky=W when you want the widget on the left side of the column sticky=W +E for center, and sticky=E for right.

For the buttons at the bottom, don't forget columnspan:

frame4 = Frame(window)
frame4.grid(row=2, column=0, sticky=E, padx=5, pady=5, columnspan=3)
Button(frame4, text=' Done ', command=done).grid(row=0, column=0, padx=7 ,pady=2, sticky=E)
Button(frame4, text='Clear', command=clear).grid(row=0,column=1, padx=7,pady=2, sticky=E)
Eric Levieil
  • 3,554
  • 2
  • 13
  • 18
  • if `frame` is not used, then how could i place the center buttons `Select button` and `Unselect button` one below the other and also inbetween two list boxes as of where it is now. and changing `sticky=E' for the buttons at the bottom, worked. Actually i didnt give a try with `columnspan=3` for the bottom frame – arvindh Jul 24 '15 at 11:47
  • @arvindh: if you put the Listboxes in row 1 with rowspan = 4 and the middle buttons on row 2 and 3? – Eric Levieil Jul 24 '15 at 12:42