I am trying to limit the number of characters that can be input in a list of Entry widgets. I tried using the following:
def character_limit(entry_text):
if len(entry_text.get()) > 0:
entry_text.set(entry_text.get()[:10])
player_names = []
for i in range(num_players):
player_names.append(tk.StringVar())
player_names[i].trace("w", lambda *args: character_limit(player_names[i]))
player_name_entry = tk.Entry(top, textvariable=player_names[i])
player_name_entry.grid(row=i, column=0)
But this only limits the last Entry widget. How can I fix this?
CodePudding user response:
The looping problem is a very commonly seen problem and to fix it, you have to store the current value of the iteration within the lambda
itself:
def character_limit(*args, entry_text):
# if len(entry_text.get()) > 0: Can remove this line as it seems to not really be doing anything
entry_text.set(entry_text.get()[:10])
for i in range(num_players):
...
player_names[i].trace("w", lambda *args, i=i: character_limit(entry_text=player_names[i]))
The reason you use *args
is because, trace
passes 3 arguments to the function itself, that we don't need mostly.
But a more better method to do this will be to use validation for the entry widgets as this will prevent you needing to create a StringVar
and trace its activity unnecessarily:
def character_limit(inp):
if len(inp) > 10:
return False
return True
player_names = []
vcmd = (root.register(character_limit), '%P')
for i in range(num_players):
player_name_entry = Entry(root, validate='key', validatecommand=vcmd)
player_name_entry.grid(row=i, column=0)
player_names.append(player_name_entry)
Read:
- tkinter creating buttons in for loop passing command arguments
- Interactively validating Entry widget content in tkinter
CodePudding user response:
The problem is not related to the widget. Variable i
is not local to the lambda
functions, so the last value of i
is used for every function.
To create local variables change your lambda into:
player_names[i].trace("w", lambda *args, n=i: character_limit(player_names[n]))
For a good description see https://docs.python.org/3/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result