Using grid() with TopLevel window not laying out widgets as expected

Question:

I’m trying to use the grid() layout manager to apply to a Toplevel window that successfully opens, but I can only get pack() to work. It seems that using the grid(row=x, column=y) isn’t working – what am I missing please?
I’m using the following code:

def messageWindow():
# create child window
win = Toplevel()
win.geometry("400x400")

# display message
message = "This is the child window"
my_label = Label(win, text=message)
my_label.grid(row=5, column=8)
# quit child window and return to root window
# the button is optional here, simply use the corner x of the child window
#close_btn = Button(win, text='Close', command=win.destroy).place(x=150, y=200) -- this works but I want to use grid()
close_btn = Button(win, text='Close', command=win.destroy).grid(row=1, column=1)

When this is triggered using a menu command, the following result is returned:
enter image description here

I would expect the grid() layout manager to distinguish between the row/column parameters that I have specified for the label and button widgets.

The same grid() layout manager does work when referring to the parent window=Tk().

Asked By: Tommo

||

Answers:

Is that what you want like this same as you screenshot?

Screenshot:

enter image description here

I merely changed row and column:

  • my_label.grid(row=0, column=1)
  • close_btn = Button(win, text=’Close’,
    command=win.destroy).grid(row=1, column=0)
Answered By: toyota Supra

Here is functioning code that works with either grid() or place(). After a bit of restructuring of the OP code, and incorporating comments from martineau and Сергей Кох, it creates root and child windows, with titles.

Assuming from the OP that the child window has only 6 rows and 9 columns, and that the Label goes in the bottom right corner, with the "Close" button in the top left corner, then rowconfigure() and columnconfigure() were used along with grid()‘s sticky parameter to properly position these widgets.

import tkinter as tk

def messageWindow():
    child_win = tk.Toplevel()
    child_win.geometry("400x400")
    child_win.title('Child')

    child_win.rowconfigure(1, weight=1)
    child_win.columnconfigure(1, weight=1)

    # display message
    message = "This is the child window"
    my_label = tk.Label(child_win, text=message)
    my_label.grid(row=5, column=8)

    # quit child window and return to root window
    # the button is optional here, simply use the corner x of the child window

    close_btn = tk.Button(child_win,
                          text='Close',
                          command=child_win.destroy)

    # Either of these two statements work: .grid() puts close_btn
    #  in the top left corner, while .place() puts it near the
    #  center with the given coordinates and window geometry.
    close_btn.grid(row=1, column=1, sticky=tk.NW)
    # close_btn.place(x=150, y=200)

if __name__ == '__main__':
    root = tk.Tk()
    root.title('This is the root window')
    root.geometry("400x200")
    messageWindow()
    root.mainloop()
Answered By: Doc
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.