如何通过一个按钮关闭多个Tkinter窗口并继续执行程序
解决Tkinter登录后无法关闭两个窗口的问题
看起来你遇到的核心问题有两个:一是调用destroy时漏掉了括号,二是在登录成功时重新使用了rootA变量名,覆盖了原来的登录窗口引用,导致无法正确关闭初始的登录界面。下面是具体的解决思路和修改后的代码:
问题分析
- 在
CheckLogin函数中,登录成功时你创建了一个新的rootA = Tk(),这会覆盖全局变量rootA原本指向的登录窗口对象,所以后续在LoginSuccessful里调用rootA.destroy()(哦对,你还漏了括号)只能关闭这个新的提示窗口,而关不了原来的登录窗口。 - Tkinter应用建议只保留一个主
Tk()实例,其他弹窗应该用Toplevel()来创建,这样窗口管理会更清晰。
解决方案步骤
- 修复
destroy()的调用:确保调用方法时加上括号,否则只是引用方法而不会执行。 - 区分窗口变量名:给登录成功的提示窗口起一个独立的名字(比如
success_win),不要覆盖登录窗口的rootA变量。 - 全局化提示窗口引用:让
LoginSuccessful能同时访问登录窗口和提示窗口的引用,从而关闭两者。 - 改用
Toplevel创建弹窗:替代新的Tk()实例,符合Tkinter的最佳实践。
修改后的完整代码
import time import openpyxl from openpyxl import load_workbook import tkinter as tk from tkinter import * import sys user1 = 'testing' # 直接全局定义,避免Function()的冗余 password1 = '0000' def Login_form(): global username, password, rootA rootA = Tk() rootA.title('User Authentication') msgbox1 = Label(rootA, text='Please Login\n') msgbox1.grid(sticky=E) username_label = Label(rootA, text='Username: ') password_label = Label(rootA, text='Password: ') username_label.grid(row=1, sticky=W) password_label.grid(row=2, sticky=W) username = Entry(rootA) password = Entry(rootA, show='*') username.grid(row=1, column=1) password.grid(row=2, column=1) login_btn = Button(rootA, text='Login', command=CheckLogin) exit_btn = Button(rootA, text='Exit', command=sys.exit) login_btn.grid(row=4, column=1) exit_btn.grid(row=4, column=2) rootA.mainloop() def CheckLogin(): global success_win # 全局化成功窗口引用 if username.get() == user1 and password.get() == password1: # 用Toplevel创建弹窗,而不是新的Tk() success_win = Toplevel(rootA) success_win.title('Authentication Check') success_win.geometry('150x100') rlbl = Label(success_win, text='\n Logged In') rlbl.pack() okay_btn = Button(success_win, text='Okay', command=LoginSuccessful) okay_btn.pack() else: error_win = Toplevel(rootA) error_win.title('Authentication Check') error_win.geometry('150x160') rlbl = Label(error_win, text='\n Invalid Login') rlbl.pack() okay_btn = Button(error_win, text='Try Again', command=error_win.destroy) okay_btn.pack() exit_btn = Button(error_win, text='Exit', command=sys.exit) exit_btn.pack() def LoginSuccessful(): # 关闭登录窗口和成功提示窗口 rootA.destroy() success_win.destroy() print("ANCD") # 这里可以继续执行你的后续任务,比如调用Insert_Rows() # Insert_Rows() def Insert_Rows(): # 你的原有逻辑,这里假设All_Users_Sheet已经定义 for rows in range(len(All_Users_Sheet)): if rows == 0: continue if All_Users_Sheet[rows][10].value is None: break else: print(All_Users_Sheet[rows][10].value) print(type(All_Users_Sheet[rows][10].value)) Login_form()
额外优化点
- 把
user1和password1直接全局定义,去掉了冗余的Function()。 - 给登录窗口的标签重命名(
username_label),避免和输入框的username变量重名,防止潜在的变量覆盖问题。 - 所有弹窗都改用
Toplevel,基于主窗口rootA创建,这样窗口层级更清晰,关闭主窗口时也会自动关闭所有子窗口(不过这里我们手动关闭了)。
这样修改后,点击Okay按钮就能同时关闭登录窗口和成功提示窗口,程序也会继续执行后续任务啦。
内容的提问来源于stack exchange,提问作者Leanne
相关产品推荐
相关产品推荐

