Alternating toplevels and the ….

…. slightly confusing case of anchor and side.

The very simplistic code below demonstrates creating two toplevel widgets and then alternating between them by pressing a simple button.  The geometry used for this example is PACK, mostly to prove we can “place” a button where we want it, including the text on the button itself.

This is pretty straightforward actually, just use attributes or wm_attributes() (they are the same command) to set the “-topmost” value to 1 or True to get it on top to start, then when its button is pressed change it the same way to 0 or False and the other toplevel widget, top2, is forced to the top of the stack.  When top2’s button is pressed we reset the focus to bring top1 back to the fore.

Its easy when you are first learning tkinter to confuse the fact that “anchor” is an attribute in PACK and GRID (but not in PLACE) that positions a widget, AND it is an attribute for all widgets having text that specifies where the text is placed in the widget.  Anchor is poorly explained in a number of places on the web.

When used in its PACK incarnation, ANCHOR has to be used in conjunction with the SIDE attribute to get what you want most of the time.

from tkinter import *
 
root=Tk()
scrW = root.winfo_screenwidth()
scrH = root.winfo_screenheight()
# assign the whole screen to our root and make the background white
wholescreen = str(scrW) + "x" + str(scrH)
root.geometry(wholescreen)
root.configure(background='white')
# when b1 (aka button #1 on toplevel top1) is pressed, top1 is forced down
# and we set the focus on top2 and button b2
def b1action():
    top1.wm_attributes("-topmost",False)
    top2.focus_set()
    b2.focus()
# when b2 (aka button 2 on top2) is pressed all we ave to do is refocus top1 and b1
def b2action():
    top1.focus_set()
    b1.focus()

def egress():
    root.destroy()
 
top1 = Toplevel(root, bg="light blue")
top1.geometry('500x400')
top1.title("Top 1 Window")
top1.wm_attributes("-topmost", 1)  # make sure top1 is on top to start
 
top2=Toplevel(root,bg="lemon chiffon")
top2.geometry('300x300')
top2.title('Top 2 Window')
 
# we have to define BOTH anchor and side attributes to place the button where we want it!
b1=Button(top1,text="Push me", command=b1action, anchor="nw")
#  #anchor="nw" will not mean anything without internal padding, which we do in pack below
b1.pack(anchor="nw", side="left", ipadx=30, ipady=30)
 
b2=Button(top2, text="Or push me", command=b2action, anchor="se")
b2.pack(side="bottom", anchor="se", ipadx=20, ipady=20)

# Just for fun, include an east exit button over on the side
b3=Button(root,text="Exit", command=egress,width=20, height=3)
b3.pack(side="right", anchor="e",padx=100)

mainloop()