首页 > 解决方案 > 关闭除 tkinter 中的启动窗口以外的所有窗口

问题描述

在下面的这段代码中,我通过每次按下特定按钮时打开定义的窗口来进行简单的路线引导,例如)主菜单 -> 教室楼层 -> 教室编号。

我正在尝试制作一个“主页”按钮,该按钮将关闭所有打开的窗口,但第一个主菜单窗口除外,其中写有 WELCOME。

例如,在我按下btn7、btn702 后,我打开了 4 个窗口。我想添加一个“主页”按钮,它将关闭 3 个新打开的窗口并让第一个窗口保持活动状态。我该如何制作这种按钮?

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()

**我一直在谷歌搜索这类问题,我想我已经得到了将“selectfloor”、“floor7”、“room702”窗口作为儿童小部件的提示。但我仍然不确定如何实现它。

标签: user-interfacetkinter

解决方案


您可以将窗口存储在列表中,然后遍历列表以销毁它们。

这是一个简化的例子。此示例使用Toplevel窗口而不是Tk. 目前尚不清楚为什么要使用 的多个实例Tk,但一般来说,您应该只拥有一个。然而,同样的技术适用于任何类型的小部件。

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()

如果您使用Toplevel而不是Tk,并且始终使窗口成为根窗口的直接子级,则可以进行优化。在这种情况下,您可以遍历 root 的所有子级,并删除任何顶级窗口。

在这种情况下,您不需要维护windows列表。

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)

推荐阅读