Home > Mobile >  Python tkinter Entry widget validation error : TypeError: 'str' object is not callable
Python tkinter Entry widget validation error : TypeError: 'str' object is not callable

Time:05-01

I am trying to use built-in input validation of Tkinter's Entry widget but I can't figure out why I receive a TypeError when entry validation is triggered. (regardless of what kind of event triggers the validation). In the simple code below, I am trying to validate only numerical input from the user. Alphabetical characters must disable the Apply button. But as soon as you enter ANY character, a "TypeError: 'str' object is not callable" is raided. Any ideas why?!

from tkinter import *
from tkinter import ttk

root = Tk()

entry_string = StringVar()
entry_field = ttk.Entry(root, textvariable=entry_string, validate='key')
apply_button = ttk.Button(root, text='Apply', state='normal')
entry_field.grid(column = 0 , row = 0)
apply_button.grid(column = 0 , row = 1)

def validate(entry):
    if str(entry).isnumeric():
        apply_button.config(state = 'normal')
        return TRUE
    else:
        return FALSE

def on_invalid():
    apply_button.config(state='disabled')


vcmd = (root.register(validate(entry_string), '%P'))
ivcmd = (root.register(on_invalid()),)
entry_field.config(validatecommand=vcmd, invalidcommand=ivcmd)
root.mainloop()

CodePudding user response:

Issue

  • Format for the validatecommand argument should be (register(f), s1, s2, ...). Your is currently (register(f, s1, s2, ...)).
  • You are passing the returned value of validate function to register, instead you need pass the function itself.

Reference

I highly recommend you to read this page from docs

Fix

import tkinter as tk
from tkinter import ttk

root = tk.Tk()

entry_string = tk.StringVar()
entry_field = ttk.Entry(root, textvariable=entry_string, validate='key')
apply_button = ttk.Button(root, text='Apply', state='normal')
entry_field.grid(column = 0 , row = 0)
apply_button.grid(column = 0 , row = 1)

def validate(value):
    if str(value).isnumeric():
        apply_button.config(state = 'normal')
        return tk.TRUE
    else:
        return tk.FALSE

def on_invalid():
    apply_button.config(state='disabled')

vcmd = (root.register(validate), '%P')
ivcmd = (root.register(on_invalid),)
entry_field.config(validatecommand=vcmd, invalidcommand=ivcmd)

root.mainloop()
  • Related