tkinter button different command for loop in dictionary not working
Replace
self.widgetdata[i] = Button(self, text=i, command=lambda: self.edit(i))
by
self.widgetdata[i] = Button(self, text=i, command=lambda i=i: self.edit(i))
Explanation: the body of the lambda function is executed when clicking the Button, so it uses the current value of i
at execution time (i.e. the index of the last created Button), not at definition time. Creating an aliased argument, forces the creation of a local variable for each loop step, each having a different value, so refering to a different Button.
Tkinter assign button command in a for loop with lambda
The problem is your lambda
expression in the for
loop. It is using the name
variable, but the name
variable gets reassigned each iteration of the for
loop, so in the end, all of the buttons get the last value that name
was assigned to in the for loop. To avoid this you can use default keyword parameters in your lambda
expression like so:
user_button = Tkinter.Button(self.root, text=name,
command=lambda name=name: self.a(name))
This binds the current value of the name
variable to the lambda's name
keyword argument each time through the loop, producing the desired effect.
Pass button text to command as arg with tkinter button
You can use default value of argument on the lambda:
for folder in os.listdir("Servers"):
btns.append(
tk.Button(
master,
text=folder,
command=lambda f=folder: handleButton(f)
)
)
Creating Tkinter buttons in a loop and setting the command for each button to take in the indices of the loop
You need to create a local variable in lambda
when using a loop
button = Button(root, text="0", height=2, width=10, command=lambda x_p=i,y_p=j: self.if_clicked_square(x_p,y_p))
button.place(x=25 + (100 * j), y=100 + (100 * i))
tkinter Button command doesn't work properly in iteration
This is a tricky little corner of Python. Remember that your lambda function isn't evaluated until the lambda is actually executed. By the time the lambda is executed, a
has the value 2
, for all three callbacks. What you need to do is "capture" the loop value, by passing it as a default parameter to the function:
dict2[a]= Button(root,text='clear',command=lambda a=a :list1[a].set('')).place(relx=0.86,rely=0.32+label_rely)
Declare buttons in a loop in Tkinter (Python3)
Here is a very simple example on how to do so, by making a list of all the 25 color and then using the conventional matrix looping and assigning items to the buttons, like:
from tkinter import *
root = Tk()
colors = ['Red','Orange','Yellow','Green','Blue','Purple','Brown','Magenta',
'Tan','Cyan','Olive','Maroon','Navy','Aquamarine','Turquoise','Silver',
'Lime','Teal','Indigo','Violet','Pink','Black','White','Gray','crimson']
colors = list(reversed(colors)) # Reversing list bc pop returns last item
def color_changer(btn,color):
btn.config(fg=color) # Change the color of the corresponding button
for i in range(5): # Number of rows
for j in range(5): # Number of column
color = colors.pop() # First color
btn = Button(root,text=color,fg='black',width=25)
btn.grid(row=i,column=j) # Place the widget
btn['command'] = lambda btn=btn,color=color: color_changer(btn,color) # Assign a command
root.mainloop()
There is a caveat here, you should define exactly 25 colors, else, you should use try
to catch the IndexError
that comes up and ignore it.
How does the function work?:
You are using lambda
to create a new nameless function that takes in btn
and color
and passes that btn
and color
to the color_changer()
. This way we can store corresponding btn
and color
, unlike if you would normally assign it like lambda: color_changer(btn,color)
, it is just going to pass the last popped item. This is usually how we assign commands for buttons inside a loop.
Alternative(to lambda
):
You can also use a nested function(avoiding lambdas
). So the function would be like:
def nester(btn,color):
def color_changer():
btn.config(fg=color)
return color_changer
and the command would be like:
btn['command'] = nester(btn,color)
This is similar to what functools.partial
does.
Related Topics
Why Does Concatenation of Dataframes Get Exponentially Slower
Find the First Instance of a Nonzero Number in a List in Python
Get Key by Value in Dictionary
How to Watch a File For Changes
Read Streaming Input from Subprocess.Communicate()
Logical Operators For Boolean Indexing in Pandas
Deploying a Minimal Flask App in Docker - Server Connection Issues
Is False == 0 and True == 1 an Implementation Detail or Is It Guaranteed by the Language
How to Import Other Python Files
How Do "And" and "Or" Act With Non-Boolean Values
Get Difference Between Two Lists
How to Determine the Encoding of Text
Tkinter Understanding Mainloop
Python + Selenium: Wait Until Element Is Fully Loaded
Get a List of Numbers as Input from the User
How to Convert Webpage into Pdf by Using Python
How to Control the Source Ip Address of a Zeromq Packet on a Machine With Multiple Ips
Why Doesn't Calling a String Method Do Anything Unless Its Output Is Assigned