Skip to content

How to Limit Character Length in Python Tkinter Widgets

A developer on a popular Python forum recently asked: “How can I limit the character count in a Tkinter window? I want to stop the user from typing more than 10 characters in an Entry field, but there doesn’t seem to be a ‘maxlength’ attribute like in HTML.”

Unlike web frameworks, Tkinter does not provide a direct property to cap input length. To solve this, you must implement a validation logic that intercepts the user’s input before it is rendered in the widget.

The Immediate Fix: Using the validatecommand

Section titled “The Immediate Fix: Using the validatecommand”

The most robust way to handle this for an Entry widget is through the built-in validation API. This allows the widget to check the content every time a key is pressed.

# Python 3.10+ (illustrative example — verify in your environment)
import tkinter as tk
def limit_input(P):
# P is the value of the entry if the edit is allowed
if len(P) <= 10:
return True
return False
root = tk.Tk()
root.title("Character Limit Example")
# Register the validation function
vcmd = (root.register(limit_input), '%P')
entry = tk.Entry(root, validate="key", validatecommand=vcmd)
entry.pack(padx=20, pady=20)
root.mainloop()

Tkinter’s validation system relies on “percent substitutions.” When you register a command, you pass specific codes to tell Tkinter what information you need to validate the input:

  • %P: The value that the text will have if the change is allowed.
  • %S: The specific string being inserted or deleted.
  • %d: The type of action (1 for insert, 0 for delete).

By using %P, we can check the length of the potential new string. If the function returns True, the keystroke is accepted; if False, the keystroke is silently discarded, preventing the user from typing past the limit.


If you prefer a more “Pythonic” approach or if you are already using a StringVar to track your input, you can use the .trace_add() method. This is useful when you want to perform other actions (like updating a character counter label) simultaneously.

# Python 3.11 (illustrative example — verify in your environment)
import tkinter as tk
def on_write(*args):
value = var.get()
if len(value) > 10:
# Manually truncate the string
var.set(value[:10])
root = tk.Tk()
var = tk.StringVar()
var.trace_add("write", on_write)
entry = tk.Entry(root, textvariable=var)
entry.pack(padx=20, pady=20)
root.mainloop()

Why this works: The trace_add("write", ...) observer fires every time the variable associated with the Entry changes. If the length exceeds 10, we programmatically set the variable back to the first 10 characters.

Note: This method can sometimes cause the cursor to jump to the end of the input field when the limit is reached, making it slightly less “smooth” for the user than the validatecommand approach.


The validatecommand with %P handles copy-pasting automatically. If a user tries to paste a 50-character string into a 10-character limit field, the validation will return False and the paste action will simply not happen. If you want to allow the paste but truncate it, the StringVar trace method is actually superior, as it allows the first 10 characters of the paste to remain.

Unlike the Entry widget, the Text (multiline) widget does not have a validatecommand property. To limit characters in a Text widget, you must bind to the <Key> event and intercept it:

# Python 3.12 (illustrative example — verify in your environment)
def limit_text(event):
if len(text_widget.get("1.0", "end-1c")) >= 100 and event.keysym not in ("BackSpace", "Delete"):
return "break" # Prevents the event from propagating

Can I limit the input to numbers only while also limiting length? Yes. In your validation function, simply add an additional check: if len(P) <= 10 and (P.isdigit() or P == ""):. The P == "" check is vital to allow the user to backspace and empty the field.

Does this work in CustomTkinter or Ttk? Yes. Both customtkinter.CTkEntry and tkinter.ttk.Entry support the validatecommand and textvariable arguments in the same way as the standard Tkinter Entry.

Is there a performance impact for long strings? For an Entry widget, the impact is negligible because the strings are short. For a Text widget with thousands of lines, calculating the length on every keystroke can cause lag. In those cases, it is better to validate only when the widget loses focus (validate="focusout") or use a debounce timer.