Python Tkinter登录窗口关闭异常求助:关闭登录窗后主窗口仍弹出
Hey there! Let's fix that annoying issue where your main window pops up even when you close the login window without logging in. Here's what's going wrong and how to fix it:
What's the Problem?
Your current code runs the main window creation logic unconditionally in the global scope, right after the login window's mainloop() finishes. This means no matter how you close the login window (either by logging in successfully or clicking the close button), the main window will always pop up. Also, the MyWindow class structure isn't following Tkinter best practices, which makes controlling the program flow harder.
The Fixed Code
Here's the revised version that stops the entire script when the login window is closed without logging in:
import sys from tkinter import * import paramiko import time from tkinter.ttk import Combobox import tkinter as tk from tkinter import ttk LARGE_FONT = ("Verdana", 12) NORM_FONT = ("Helvetica", 10) SMALL_FONT = ("Helvetica", 8) # Global variables for login credentials username1 = "" password1 = "" def popupmsg(msg): popup = tk.Tk() popup.wm_title("Error") label = ttk.Label(popup, text=msg, font=NORM_FONT) label.pack(side="top", fill="x", pady=10) B1 = ttk.Button(popup, text="Try Again", command=popup.destroy) B1.pack() popup.mainloop() class LoginWindow(): def __init__(self): self.root = tk.Tk() self.login_success = False # Flag to track login status # Set window icon image = r"D:\Python\My Projects\Nokia1.png" icon = PhotoImage(file=image) self.root.call('wm', 'iconphoto', self.root._w, icon) # Create canvas and widgets self.canvas1 = tk.Canvas(self.root, width=400, height=300) self.canvas1.pack() image_bg = tk.PhotoImage(file=r"D:\Python\My Projects\Nokia.png") self.canvas1.create_image(50, 10, image=image_bg, anchor=tk.NW) # Username field self.webui_username = tk.Label(self.root, text="Enter Username") self.canvas1.create_window(125, 150, window=self.webui_username) self.webui_username_Entry = tk.Entry(self.root) self.canvas1.create_window(250, 150, window=self.webui_username_Entry) # Password field self.webui_password = tk.Label(self.root, text="Enter Password") self.canvas1.create_window(125, 200, window=self.webui_password) self.webui_password_Entry = tk.Entry(self.root, show="*") self.canvas1.create_window(250, 200, window=self.webui_password_Entry) # Login button self.button1 = tk.Button(text='Login', command=self.done, bg='black', fg='white', font=('helvetica', 9, 'bold')) self.canvas1.create_window(200, 250, window=self.button1) # Bind close event to custom handler self.root.protocol("WM_DELETE_WINDOW", self.on_closing) self.root.title('Nokia Login') self.root.mainloop() def done(self): """Handle login button click""" global username1, password1 if self.webui_username_Entry.get() == "alcatel" and self.webui_password_Entry.get() == "Nokia@2016": self.login_success = True username1 = self.webui_username_Entry.get() password1 = self.webui_password_Entry.get() self.root.destroy() # Close login window else: popupmsg("Wrong Username or password") def on_closing(self): """Handle when login window is closed via close button""" self.root.destroy() sys.exit() # Terminate entire script class MainWindow(): def __init__(self, win): self.new_username = Label(win, text='New Username') self.new_password = Label(win, text='New Password') self.profile = Label(win, text='Profile Domain') self.result = Label(win, text='Result') global webui_username, webui_Password, outbox, cb webui_username = self.t1 = Entry(bd=3) webui_Password = self.t2 = Entry() outbox = self.outbox_E = Entry() self.new_username.place(x=100, y=50) self.t1.place(x=200, y=50) self.new_password.place(x=100, y=100) self.t2.place(x=200, y=100) self.profile.place(x=100, y=150) self.b2 = Button(win, text='Create', command=self.auth) self.b2.place(x=200, y=200) self.result.place(x=100, y=240) self.outbox_E.place(x=200, y=240, width=200, height=40) # Dropdown list self.data = ("Voda", "unknown", 'All Network') cb = Combobox(win, values=self.data) cb.place(x=200, y=150) def auth(self): """Authentication logic for SSH connection""" global ipa, ssh ipa = "xx.xx.xx.xx" try: ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(ipa, 22, 'root', 'Nokia@2016') shell = ssh.invoke_shell() print("Auth Success") except paramiko.AuthenticationException: print("\nWrong username or Password, Please try again\n") except TimeoutError: print("\nIP is not reachable. please check connection\n") # Handle profile selection profile_unknown = " unknown" profile_Voda = " Voda" profile_All = ' "Voda","unknown"' if cb.get() == "unknown": profile_d = profile_unknown elif cb.get() == "Voda": profile_d = profile_Voda elif cb.get() == 'All Network': profile_d = profile_All # Main program flow if __name__ == "__main__": # Start login window login_app = LoginWindow() # Only start main window if login was successful if login_app.login_success: window = Tk() image = r"D:\Python\My Projects\Nokia2.png" icon = PhotoImage(file=image) window.call('wm', 'iconphoto', window._w, icon) window.title('Vendor tool') window.geometry("500x400+10+10") mywin = MainWindow(window) window.mainloop()
Key Changes Explained
- Refactored Login Window: Created a dedicated
LoginWindowclass with a proper__init__method, and added alogin_successflag to track if the user logged in successfully. - Close Event Handling: Used
self.root.protocol("WM_DELETE_WINDOW", self.on_closing)to bind the window close event to a handler that callssys.exit(), terminating the entire script when the login window is closed without logging in. - Conditional Main Window Launch: The main window is only created and launched if the
login_successflag isTrue, which only happens when the user enters correct credentials and clicks the login button. - Cleaner Class Structure: Separated login and main window logic into distinct classes for better readability and maintainability.
内容的提问来源于stack exchange,提问作者NewCoderBiggnerInThisLife




