如何在Python3.7的Tkinter中创建模态窗口——密码管理GUI开发求助
Hey there! Let's fix up your Tkinter password manager to get that modal popup working correctly—right now, your code has a couple of small issues that are keeping the main window interactive when the second window is open, plus some best practices we can clean up for better security and reliability.
Key Issues in Your Current Code
- You're using
Tk()to create the second window, but Tkinter is designed to have only one mainTkinstance per application. For secondary windows, you should useToplevel()instead. - Your second window isn't set to be modal (blocking interaction with the main window). We'll fix that with two simple methods to lock focus to the popup.
- You're calling
root2.mainloop()again insecondwindow()—this is redundant because your main window already runsroot.mainloop(). - You don't close the
passwords.txtfile after reading it; using awithstatement is safer and cleaner (it auto-closes the file for you). - Your password entry field shows typed characters—adding
show="*"will hide them for better security.
Modified Working Code
Here's the adjusted code with all fixes applied:
from tkinter import * from tkinter import ttk # Safely read passwords file with auto-close list1 = [] with open("passwords.txt", "r") as f: for item in f.readlines(): item = item.strip() # Clean up line endings and whitespace if item: # Skip empty lines in the file list1.append(item) def secondwindow(): # Use Toplevel for secondary windows (attached to main root) root2 = Toplevel(root) root2.title("Secure Your Password") root2.configure(bg="black") root2.geometry('700x600') # Make window modal (blocks main window interaction) root2.transient(root) # Ties popup to main window (stays on top) root2.grab_set() # Locks focus to popup until it's closed frame_color = "#%02x%02x%02x" % (150,150,150) # Create A Main frame main_frame = Frame(root2, bg=frame_color) main_frame.pack(fill=BOTH,expand=1) # Create Frame for X Scrollbar sec = Frame(main_frame, bg=frame_color) sec.pack(fill=X,side=BOTTOM) # Create A Canvas my_canvas = Canvas(main_frame, bg="black") my_canvas.pack(side=LEFT,fill=BOTH,expand=1) # Add A Scrollbars to Canvas x_scrollbar = ttk.Scrollbar(sec,orient=HORIZONTAL,command=my_canvas.xview) x_scrollbar.pack(side=BOTTOM,fill=X) y_scrollbar = ttk.Scrollbar(main_frame,orient=VERTICAL,command=my_canvas.yview) y_scrollbar.pack(side=RIGHT,fill=Y) # Configure the canvas my_canvas.configure(xscrollcommand=x_scrollbar.set) my_canvas.configure(yscrollcommand=y_scrollbar.set) my_canvas.bind("<Configure>",lambda e: my_canvas.config(scrollregion= my_canvas.bbox(ALL))) # Create Another Frame INSIDE the Canvas second_frame = Frame(my_canvas, bg=frame_color) # Add that New Frame a Window In The Canvas my_canvas.create_window((0,0),window=second_frame, anchor="nw") f = Frame(second_frame, borderwidth=2, relief=SUNKEN, bg=frame_color) f.pack(side=TOP, fill=X) Label(f, text="Secure Your Password", fg="white", bg=frame_color, font="Algerian 35 italic").pack() f1 = Frame(second_frame, bg="black") f1.pack(fill=BOTH, side=TOP, expand=1) Label(f1, text="Application", fg="red", bg="black", font="Calibri 20 bold", pady=10, padx=60).grid(row=1, column=1) Label(f1, text="Username", fg="red", bg="black", font="Calibri 20 bold", pady=10, padx=210).grid(row=1, column=2) Label(f1, text="Password", fg="red", bg="black", font="Calibri 20 bold", pady=10, padx=198).grid(row=1, column=3, padx=140) for i in range(len(list1)): application = list1[i].split(";;;")[0] username = list1[i].split(";;;")[1] password = list1[i].split(";;;")[2] Label(f1, text=application, fg="white", bg="black", font="Calibri 20 bold", pady=5).grid(row=i+2, column=1) Label(f1, text=username, fg="white", bg="black", font="Calibri 20 bold", pady=5).grid(row=i+2, column=2) Label(f1, text=password, fg="white", bg="black", font="Calibri 20 bold", pady=5).grid(row=i+2, column=3) def checkPassword(password, l): if password == "a": # Hide login window instead of destroying it (optional, but more flexible) root.withdraw() secondwindow() # If you want to close the login window entirely, use root.destroy() instead else: l.config(text="Wrong Password") def password_window(): root.geometry('450x270') root.title("Secure Your Password") root.minsize(450, 270) root.maxsize(450, 270) root.configure(bg="black") Label(root, text="Secure Your Password", fg="white", bg="black", font="Algerian 24 italic").pack(side=TOP) Label(root, text="Your Password", fg="white", bg="black", font="Clibri 15").pack(pady=10) password = StringVar() # Add show="*" to hide typed password characters Entry(root, textvariable=password, bg="grey", fg="white", font="Calibri 15 bold", show="*").pack(pady=10) Button(root, text="Login", bg="grey", fg="white", activebackground="grey", font="Calibri 10", command=lambda: checkPassword(password.get(), l)).pack(pady=8) l = Label(root, fg="red", bg="black", font="Clibri 10 bold") l.pack() # Initialize main Tk instance first (best practice) root = Tk() password_window() root.mainloop()
What We Changed & Why
- File Reading with
with: Ensures the file is automatically closed after reading, preventing resource leaks. We also addedstrip()to clean up line endings more reliably and skip empty lines. Toplevel()Instead ofTk(): Tkinter apps should only have one mainTkinstance.Toplevel()creates a secondary window attached to the main root, which is the correct approach for popups.- Modal Window Setup:
root2.transient(root): Makes the popup a child of the main window (it stays on top and follows the main window's focus).root2.grab_set(): Locks all interaction to the popup until it's closed—exactly what you wanted!
- Removed Redundant
mainloop(): The main window'sroot.mainloop()handles all window events, so we don't need a separate loop for the popup. - Password Field Security: Added
show="*"to the entry field to hide typed characters, which is essential for password inputs. - Flexible Login Flow: Changed
root.destroy()toroot.withdraw()to hide the login window instead of closing it. If you want to bring it back later, you can add a button to the popup that callsroot.deiconify().
Testing Your
passwords.txt Your existing file content works perfectly with the modified code—it will split each line by ;;; and display the application, username, and password in the table correctly.
内容的提问来源于stack exchange,提问作者Pomogranade
相关产品推荐
相关产品推荐

