如何解决Tkinter Toplevel窗口调用destroy()无法正常关闭问题
Toplevel窗口无法完全关闭的问题解决
问题核心
点击弹窗按钮后,调用.destroy()仅清空了窗口内容,但滚动条和窗口框架仍残留,无法彻底关闭弹窗。
错误原因
在创建按钮的partial调用中,错误传递了second_frame(弹窗内的子框架)作为要销毁的对象,而非真正的Toplevel窗口实例popup3。因此实际销毁的只是内部子框架,而非整个弹窗窗口。
修正步骤
- 修正
partial的传参,将second_frame替换为popup3,确保销毁的是整个弹窗 - 优化滚动区域的绑定逻辑,改为监听子框架的尺寸变化,避免不必要的滚动区域更新
- 调整主框架的布局方式,用
pack替代grid,避免布局错位
修正后的完整代码
import tkinter from tkinter import * from functools import partial placelist = ["99999|123|FAKE ST|44|MADEUP TOWNSHIP","99999|555|NOTAREAL AVE|44|MADEUP TWP"] proj = tkinter.Tk() proj.geometry('500x500') def create_popup_3(): popup3 = tkinter.Toplevel() popup3.geometry("500x500") popup3.title("Choose Result") main_frame = Frame(popup3) main_frame.pack(fill=BOTH, expand=1) # 改用pack填充整个弹窗 my_canvas = Canvas(main_frame) my_canvas.pack(side=LEFT, fill=BOTH, expand=1) my_scrollbar = tkinter.Scrollbar(main_frame, orient=VERTICAL, command=my_canvas.yview) my_scrollbar.pack(side=RIGHT, fill=Y) my_canvas.configure(yscrollcommand=my_scrollbar.set) second_frame = Frame(my_canvas) # 绑定子框架的尺寸变化来更新滚动区域,更准确 second_frame.bind('<Configure>', lambda e: my_canvas.configure(scrollregion=my_canvas.bbox("all"))) for option3 in placelist: optionsplit = option3.split('|') placesin = optionsplit[0].strip() s_num = optionsplit[1].strip() s_name = optionsplit[2].strip() twp = optionsplit[3].strip() twp_name = optionsplit[4].strip() # 修正partial参数,传递popup3而非second_frame button3 = tkinter.Button(second_frame, text=f"{s_num} {s_name}, {twp_name}", command=partial(button_click_3, option3, popup3)) button3.pack(pady=10) my_canvas.create_window((0,0), window=second_frame, anchor="nw") def button_click_3(option3, popup3): optionsplit = option3.split('|') munistrin = optionsplit[0].strip() s_name = optionsplit[2].strip() s_num = optionsplit[1].strip() twp = optionsplit[3].strip() Street_Rin.delete(0, END) Street_Rin.insert(0, munistrin) Street_Name.delete(0, END) Street_Name.insert(0, s_name) Street_Address.delete(0, END) Street_Address.insert(0, s_num) Muni_Code.delete(0, END) Muni_Code.insert(0, twp) popup3.destroy() # 现在销毁的是整个Toplevel窗口 sendbutton = tkinter.Button(text='SEND', command=create_popup_3) sendbutton.pack() Street_Address = Entry(bd=1, width=7, justify=LEFT, font=("Courier New", 12)) Street_Address.pack() Street_Name = Entry(bd=1, width=23, font=("Courier New", 12)) Street_Name.pack() Apt_No = Entry(bd=1, width=5, font=("Courier New", 12)) Apt_No.pack() Muni_Code = Entry(bd=1, width=5, font=("Courier New", 12)) Muni_Code.pack() Street_Rin = Entry(bd=1, width=7, justify=LEFT, font=("Courier New", 12)) Street_Rin.pack() proj.mainloop()
关键说明
- 销毁对象正确:确保传递给
button_click_3的是Toplevel窗口实例popup3,调用.destroy()才能彻底关闭整个弹窗 - 滚动区域优化:监听子框架
second_frame的<Configure>事件,只有当子框架尺寸变化时才更新滚动区域,避免Canvas自身尺寸变化时的无效更新 - 布局优化:主框架
main_frame改用pack(fill=BOTH, expand=1),使其填充整个Toplevel窗口,避免原grid布局导致的顶部空白
内容的提问来源于stack exchange,提问作者PKovitch734
相关产品推荐
相关产品推荐

