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

如何在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 main Tk instance per application. For secondary windows, you should use Toplevel() 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 in secondwindow()—this is redundant because your main window already runs root.mainloop().
  • You don't close the passwords.txt file after reading it; using a with statement 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
  1. File Reading with with: Ensures the file is automatically closed after reading, preventing resource leaks. We also added strip() to clean up line endings more reliably and skip empty lines.
  2. Toplevel() Instead of Tk(): Tkinter apps should only have one main Tk instance. Toplevel() creates a secondary window attached to the main root, which is the correct approach for popups.
  3. 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!
  4. Removed Redundant mainloop(): The main window's root.mainloop() handles all window events, so we don't need a separate loop for the popup.
  5. Password Field Security: Added show="*" to the entry field to hide typed characters, which is essential for password inputs.
  6. Flexible Login Flow: Changed root.destroy() to root.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 calls root.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 07:22:32