Fix No Module Named Tkinter Error in Python

Hi there! So, I’m working on building a basic Tkinter program that lets the user enter a password, and if it’s correct, it takes them to another page (or does something). The idea is that if the user enters a wrong password, a small error message saying “Incorrect Password” should appear and then disappear after 2 seconds. Sounds simple enough, right?

Well, it works perfectly the first time I enter a wrong password, the error message shows up, and after 2 seconds, it disappears just as expected. But then, if I enter the wrong password again, nothing happens. No error message, just a flood of errors that I can’t figure out.

I’ve included the code below, if any of you smart folks can spot what I’m doing wrong;

Error Code:

codefrom tkinter import *
import threading

master_pwd = "yoyodojo"
pwd_correct = False

root = Tk()
root.geometry("1080x720")

password_frame = Frame(root, bg="#D3D3D3", highlightbackground="black", highlightthickness=3)
password_frame.place(relwidth=0.4, relheight=0.25, relx=0.3, rely=0.325)

incorrect_label = Label(password_frame, text="Incorrect Password", font="Helvetica, 10", foreground="Red",
background="#D3D3D3")

def hide_incorrect_label():
incorrect_label.destroy()

def check_pwd(inputted_pwd):
if inputted_pwd == master_pwd:
global pwd_correct
pwd_correct = True
root.destroy()
else:
pwd_correct = False
password_input.delete(0, END)
incorrect_label.place(relx=0.33, rely=0.82)
x = threading.Timer(2.0, hide_incorrect_label)
x.start()

password_input = Entry(password_frame, relief=RIDGE, bg="#4f4f4f", fg="white", font="Helvetica, 14",
justify="center")
password_input.bind("<Return>", (lambda event: check_pwd(password_input.get())))
password_input.place(relwidth=0.8, relheight=0.2, relx=0.1, rely=0.6)

pwd_label = Label(password_frame, text="Enter Master Password:", font="Helvetica, 24", background="#D3D3D3")
pwd_label.pack(pady=20)

root.mainloop()

Here is the error I am getting:

codeException in Tkinter callback

Traceback (most recent call last):

File "C:\Users\benma\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
return self.func(*args)

File "C:\Users\benma\Documents\Coding\File Hider\Code\Gui.py", line 37, in <lambda>
password_input.bind("<Return>", (lambda event: check_pwd(password_input.get())))

File "C:\Users\benma\Documents\Coding\File Hider\Code\Gui.py", line 30, in check_pwd
incorrect_label.place(relx=0.33, rely=0.82)

File "C:\Users\benma\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 2477, in place_configure
self.tk.call(_tkinter.TclError: bad window path name ".!frame.!label"

Here’s a correct and well-documented version of your code, along with an explanation of how it works:

Corrected Code:

codefrom tkinter import *
import threading

# Global variables
master_pwd = "yoyodojo" # The correct password
pwd_correct = False # Track whether the correct password was entered

# Create the main root window
root = Tk()
root.geometry("1080x720") # Set the size of the window

# Create a frame to hold the password input widgets
password_frame = Frame(root, bg="#D3D3D3", highlightbackground="black", highlightthickness=3)
password_frame.place(relwidth=0.4, relheight=0.25, relx=0.3, rely=0.325)

# Label to display incorrect password message (initially hidden)
incorrect_label = Label(password_frame, text="Incorrect Password", font=("Helvetica", 10),
foreground="Red", background="#D3D3D3")

def hide_incorrect_label():
"""
Hide the 'Incorrect Password' label after 2 seconds.
"""
incorrect_label.place_forget() # Use place_forget() instead of destroy() to hide

def check_pwd(inputted_pwd):
"""
Check if the inputted password matches the master password.
If it matches, close the root window. If not, show the error label.
"""
global pwd_correct
if inputted_pwd == master_pwd:
pwd_correct = True
root.destroy() # Close the window if the password is correct
else:
pwd_correct = False
password_input.delete(0, END) # Clear the input field
incorrect_label.place(relx=0.33, rely=0.82) # Show the incorrect password message
threading.Timer(2.0, hide_incorrect_label).start() # Hide the message after 2 seconds

# Create the password input field
password_input = Entry(password_frame, relief=RIDGE, bg="#4f4f4f", fg="white", font=("Helvetica", 14),
justify="center", show="*") # 'show="*"' masks the input
password_input.bind("<Return>", lambda event: check_pwd(password_input.get())) # Bind Enter key to password check
password_input.place(relwidth=0.8, relheight=0.2, relx=0.1, rely=0.6)

# Label prompting the user to enter the password
pwd_label = Label(password_frame, text="Enter Master Password:", font=("Helvetica", 24), background="#D3D3D3")
pwd_label.pack(pady=20)

# Run the GUI event loop
root.mainloop()

Explanation:

  1. Window Initialization:
    • We create a Tkinter window (root) and set its size to 1080×720 pixels using geometry().
  2. Password Frame:
    • A Frame is used to group the password input field and labels. This makes the UI more structured.
  3. Label for Incorrect Password:
    • We define a label (incorrect_label) to show an error message if the password is incorrect. Initially, this label is hidden.
  4. Password Input and Binding:
    • The Entry widget is used for the password input. We add show="*" to mask the input (commonly used for passwords).
    • We bind the Enter key event (<Return>) to the function that checks the password, so users can press Enter to submit.
  5. Password Checking Function (check_pwd):
    • If the input matches master_pwd, we set pwd_correct to True and close the window using root.destroy().
    • If the password is incorrect, the input field is cleared, and the error label is shown for 2 seconds using threading.Timer.
  6. Timer for Error Message:
    • threading.Timer allows the error label to disappear after 2 seconds. Instead of destroying the label, we use place_forget() to hide it. This is more efficient than destroying and recreating it.
  7. Event Loop (root.mainloop()):
    • This starts the Tkinter event loop, keeping the GUI active and responsive to user inputs.

Final Thoughts:

This code provides a simple and functional password verification GUI using Tkinter. Here are some key improvements and recommendations:

  • Error Handling: Instead of destroying the label every time, we use place_forget() to hide it, which is more efficient.
  • Input Masking: Adding show="*" to the password input field improves security by masking the entered text.
  • Threading: Using threading.Timer ensures that the GUI remains responsive while the error message is temporarily displayed.
  • Future Improvements:
    • You could add functionality to limit the number of attempts.
    • Implement more advanced security practices (like hashing passwords) if this were part of a real application.

This version ensures good user experience and code readability, while also being maintainable and easy to understand.

Related blog posts