user693861
user693861

Reputation: 359

One frame at top of window, one at bottom

I have two textboxes, I'd like the first one to be at the very top of the window and the other at the very bottom. I'm using python 2.7, this is what I've tried:

from Tkinter import *
import ttk

def main():
    root = Tk()
    root.title("Testing")

    root_frame = ttk.Frame(root, padding="3 3 3 3")
    root_frame.grid(column=0, row=0, sticky=(N, W, E, S))
    root_frame.columnconfigure(0, weight=1)
    root_frame.rowconfigure(0, weight=1)

    frame1 = ttk.Frame(root_frame, padding="3 3 3 3")
    frame1.grid(column=0, row=0, sticky=(N, W, E))
    frame1.rowconfigure(1, weight=1)
    frame1.columnconfigure(0, weight=1)

    frame2 = ttk.Frame(root_frame, padding="3 3 3 3")
    frame2.grid(column=0, row=1, sticky=(W, E, S))

    ttk.Label(frame1, text="This is frame 1").grid(column=0, row=0, sticky=(W, E))
    ttk.Label(frame2, text="This is frame 2").grid(column=0, row=0, sticky=(W, E))

    root.mainloop()

if __name__ == "__main__":
    main()

It just puts the second textbox directly under the first one. What am I doing wrong?

Thanks

e: per Bryan's suggestion, I tried two more things:

Using invisible middle row:

from Tkinter import *
import ttk

def main():
    root = Tk()
    root.title("Testing")

    root_frame = ttk.Frame(root, padding="3 3 3 3")
    root_frame.grid(column=0, row=0, sticky=(N, W, E, S))
    root_frame.grid_rowconfigure(1, weight=1)

    frame1 = ttk.Frame(root_frame, padding="3 3 3 3")
    frame1.grid(column=0, row=0, sticky=(N, W, E))

    frame2 = ttk.Frame(root_frame, padding="3 3 3 3")
    frame2.grid(column=0, row=2, sticky=(W, E, S))

    ttk.Label(frame1, text="This is frame 1").grid(column=0, row=0, sticky=(W, E))
    ttk.Label(frame2, text="This is frame 2").grid(column=0, row=0, sticky=(W, E))

    root.mainloop()

if __name__ == "__main__":
    main()

Pack instead of grid:

from Tkinter import *
import ttk

def main():
    root = Tk()
    root.title("Testing")

    root_frame = ttk.Frame(root, padding="3 3 3 3")
    root_frame.grid(column=0, row=0, sticky=(N, W, E, S))

    frame1 = ttk.Frame(root_frame, padding="3 3 3 3")
    frame1.pack(side="top", fill="x")

    frame2 = ttk.Frame(root_frame, padding="3 3 3 3")
    frame2.pack(side="bottom", fill="x")

    ttk.Label(frame1, text="This is frame 1").grid(column=0, row=0, sticky=(W, E))
    ttk.Label(frame2, text="This is frame 2").grid(column=0, row=0, sticky=(W, E))

    root.mainloop()

if __name__ == "__main__":
    main()

Both still behave the same as my original code.

Upvotes: 0

Views: 2327

Answers (1)

Bryan Oakley
Bryan Oakley

Reputation: 386240

If you want one at the top and one at the bottom, the easiest solution is to use pack since it is designed to put widgets along the edges of a container. For example:

frame1.pack(side="top", fill="x")
frame2.pack(side="bottom", fill="x")

If you want to use grid, what I would do is put the top one in row 0, the bottom one in row 2, and have an empty row 1 that is configured to take up all the extra space:

frame1.grid(row=0, sticky="ew")
frame2.grid(row=2, sticky="ew")
root_frame.grid_rowconfigure(1, weight=1)

In either case, you must also make sure that the frame you are putting these widgets into also is packed/gridded correctly. The above code works, but you aren't making it so their parent also expands to fill the whole window.

Since you are using grid to put the root_frame inside root, make sure the row and column it is in is given a weight:

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

Upvotes: 1

Related Questions