Nathan Tew
Nathan Tew

Reputation: 747

Cannot create frame in Toplevel window

I have 1 root window and a toplevel window, and I want to put stuff in a frame in the toplevel window. However, the frame (rather the label in it) appears in the root window.

Screenshot of the windows.

Screen Shot

from tkinter import *

root = Tk()

Label(root, text="label1").pack()

newWindow = Toplevel(root)

Label(newWindow, text="label2").pack()
frame2 = Frame(newWindow).pack()
Label(frame2, text="framelabel2").pack()

root.mainloop()

Upvotes: 2

Views: 1340

Answers (2)

ParvBanks
ParvBanks

Reputation: 1436

You don't need two frames in this case, just use grid to align the labels: The column, row format also makes it easier to read & you also have other options such as padx, pady, sticky for more flexibility of design.

import tkinter as tk

root = tk.Tk()
frame = tk.Frame(root)
frame.grid()
root.title("Tkinter Window")  # Replace with anything else you want
label1 = tk.Label(root, text="Label1").grid(column=0,row=0)
label2= tk.Label(root,text="Label2").grid(column=0,row=1)
root.mainloop()

You can learn more about grid here.

Upvotes: -1

Mike - SMT
Mike - SMT

Reputation: 15226

You need to pack frame2 on a new line like this:

from tkinter import *

root = Tk()

Label(root, text="label1").pack()

newWindow = Toplevel(root)

Label(newWindow, text="label2").pack()
frame2 = Frame(newWindow)
frame2.pack() # pack frame2 on new line here.
Label(frame2, text="framelabel2").pack()

root.mainloop()

The reason your framelabel2 label is getting placed on the root window is due to frame2 being == to None as pack() returns None. Because you try to pack a widget to None tkinter defaults that widget to the root window in an attempt to place that widget somewhere.

Simple fix is to make sure you always do pack(), grid() or place() on a new line when it comes to defining frames or any container for that matter.

Upvotes: 4

Related Questions