You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Tkinter Toplevel窗口调用destroy()无法正常关闭问题

Toplevel窗口无法完全关闭的问题解决

问题核心

点击弹窗按钮后,调用.destroy()仅清空了窗口内容,但滚动条和窗口框架仍残留,无法彻底关闭弹窗。

错误原因

在创建按钮的partial调用中,错误传递了second_frame(弹窗内的子框架)作为要销毁的对象,而非真正的Toplevel窗口实例popup3。因此实际销毁的只是内部子框架,而非整个弹窗窗口。

修正步骤

  1. 修正partial的传参,将second_frame替换为popup3,确保销毁的是整个弹窗
  2. 优化滚动区域的绑定逻辑,改为监听子框架的尺寸变化,避免不必要的滚动区域更新
  3. 调整主框架的布局方式,用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 11:02:09