In this code below, I made a simple route guidance by opening defined windows each time I press a specific button e.g.) Mainmenu -> Classroom Floor -> Classroom No.
I'm trying to make a 'Home' button that will close all open windows except for the first Main Menu window with WELCOME written.
For example, after I press btn7, btn702, then I have 4 windows open. I would like to add a 'Home' button that will close 3 newly open windows and leave the first window alive. How might I make this kind of button?
from os import system
from tkinter import *
from PIL import ImageTk, Image
mainmenu = Tk()
mainmenu.title("CAU 310 GUIDE MAP")
mainmenu.geometry("1280x800 0 0")
canvas = Canvas(mainmenu, width = 1280, height = 800)
canvas.pack(fill='both', expand = True)
canvas.create_text(640, 250, text = 'WELCOME', font=times 45)
btnclassroom = Button(mainmenu, padx=5, pady=5,text="Classroom", font="times 30", command=selectfloor)
btnclassroom.place(x=140, y=570)
def selectfloor():
mainmenu = Tk()
mainmenu.title("DESTINATION")
mainmenu.geometry("1280x800 0 0")
mainmenu.config(bg='white')
canvas = Canvas(mainmenu, width = 1280, height = 800)
canvas.pack(fill='both', expand = True)
canvas.create_text(640, 150, text = 'Select floor of classroom', font='Arial 40')
btn7=Button(mainmenu, padx=4, pady=4, text="7F", font="Arial 42 bold", command=floor7)
btn7.place(x=160-5, y=490)
def floor7():
mainmenu = Tk()
mainmenu.title("FLOOR 7")
mainmenu.geometry("1280x800 0 0")
canvas = Canvas(mainmenu, width = 1280, height = 800)
canvas.pack(fill='both', expand = True)
canvas.create_text(640, 150, text = 'Select classroom No.', font='Arial 40')
btn702=Button(mainmenu, padx=3, pady=3, text="No.702", font="Arial 38 bold", command=room702)
btn702.place(x=100 220*1, y=240)
mainmenu.mainloop()
def room702():
mainmenu = Tk()
mainmenu.title("Elevator 1")
mainmenu.geometry("1280x800 0 0")
lobby = ImageTk.PhotoImage(Image.open("1F_elevator1.jpg"), master=mainmenu)
canvas = Canvas(mainmenu, width = 1280, height = 800)
canvas.pack(fill='both', expand = True)
canvas.create_image(0, 0, image=lobby,anchor = "nw")
mainmenu.mainloop()
mainmenu.mainloop()
**I've been googling around for this kind of matter, and I think I've got a hint of making the 'selectfloor', 'floor7', 'room702' window as a children widget. But I'm still not sure how to make it happen.
CodePudding user response:
You can store the windows in a list, and then iterate over the list to destroy them.
Here's a simplified example. This example uses Toplevel
windows rather than instances of Tk
. It's not clear why you're using multiple instances of Tk
, but in general you should only ever have one. This same technique works with any sort of widgets, however.
import tkinter as tk
windows = []
def delete_all_but_first():
for window in windows[1:]:
window.destroy()
def new_window():
window = tk.Toplevel(root)
windows.append(window)
window.title(f"Window #{len(windows)}")
root = tk.Tk()
windows.append(root)
del_all = tk.Button(root, text="Delete all", command=delete_all_but_first)
new = tk.Button(root, text="New window", command=new_window)
new.pack(side="top", padx=20, pady=20)
del_all.pack(side="top", padx=20, pady=20)
root.mainloop()
There's an optimization you can make if you use Toplevel
instead of Tk
, and if you always make the windows direct children of the root window. In that case you can just iterate over all children of root, and delete any window that is a top-level.
In this case, you don't need to maintain the windows
list.
def delete_toplevels():
for child in root.winfo_children():
if child.winfo_class() == "Toplevel":
child.destroy()
def new_window():
window = tk.Toplevel(root)
window.title(f"Window #{len(windows)}")
...
del_all = tk.Button(root, text="Delete all", command=delete_toplevels)