Luther
Luther

Reputation: 574

Tkinter Entry Validation -- how to use %W

I can refer to the widget by its construction variable as shown but according to what's printed, W should also work since apparently W and new_user_input both refer to the widget name. I've been working with Tkinter's built-in validation for a few days and this is the only problem I keep having. %P works as expected but %W does not. I don't know what I'm doing wrong. I was using this in a class and pulled it out to simplify the code but the error message is the same either way.

import tkinter as tk

def validate1(W, P):
    print("W is", W)
    print("new_user_input is", new_user_input)
    all_users = ["Bob", "Nancy"]
    valid = P not in all_users
    print("valid is", valid)
    if valid is False:
        new_user_input.bell() # works
        W.delete(0,tk.END) # doesn't work

    return valid

root = tk.Tk()

vcmd1 = (root.register(validate1), "%W", "%P")

new_user = tk.Label(
    root, 
    text="New user name:")
new_user_input = tk.Entry(
    root,
    validate="focusout",
    validatecommand=vcmd1)
new_user.grid()
new_user_input.grid()
tk.Entry(root).grid()

root.mainloop()

output:

W is .15065808
new_user_input is .15065808
valid is False
Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\LUTHER\AppData\Local\Programs\Python\Python35-32\lib\tkinter\__init__.py", line 1549, in __call__
    return self.func(*args)
  File "C:\tkinter_code\example_code\widget_variable_in_tkinter_validation.py",
line 13, in validate1
    W.delete(0,tk.END)
AttributeError: 'str' object has no attribute 'delete'

Upvotes: 1

Views: 354

Answers (1)

Henry Yik
Henry Yik

Reputation: 22493

W returns a string. You can check by type(W):

print("W is", W, type(W))

#W is .!entry <class 'str'>

To get the actual widget object, use nametowidget method:

def validate1(W, P):
    widget = root.nametowidget(W)
    print("W is", widget, type(widget))

#W is .!entry <class 'tkinter.Entry'>

Upvotes: 2

Related Questions