How to change the text of a specific button in Python [duplicate] - python

This question already has answers here:
tkinter creating buttons in for loop passing command arguments
(3 answers)
Closed 1 year ago.
I'm using tkinter and this problem bothers me a lot.
My goal:
Create several buttons
When clicking a specific button, change the text shown on that button
I tried the codes below, but no matter what button I clicked, only the last one got changed.
import tkinter as tk
list1 = []
def update_btn_text(index):
list1[index].set('new')
for i in range(10):
btn_text = tk.StringVar()
list1.append(btn_text)
btn = tk.Button(root, textvariable=list1[i], command=lambda: update_btn_text(i))
btn_text.set('button' + str(i+1))
btn.pack()
root.mainloop()
I guess the problem is because of the i value, but how can I fix it?
Thanks a lot!

You have to create a local variable for every iteration and pass it as a value in updatd_btn_text()
command=lambda i=i: update_btn_text(i)
Also you could try this for configuring text of the button
def update_btn_text(index,button):
button.config(text=list1[index])
for i in range(10):
btn = tk.Button(root)
btn.pack()
btn.config (command=lambda i=i, btn=btn: update_btn_text(i, btn))

Related

The buttons commands are automatically being executed in tkinter [duplicate]

This question already has answers here:
Why is my Button's command executed immediately when I create the Button, and not when I click it? [duplicate]
(5 answers)
How to pass arguments to a Button command in Tkinter?
(18 answers)
Closed 2 years ago.
I am trying to learn how to use tkinter and encountered a problem with buttons. What I think is happening is when I start the program it automatically calls the functions of the buttons whenever they are initialized.
code in question:
import tkinter as tk
test = tk.Tk()
x = lambda a: int((a - (a) % 3) / 3)
for i in range(9):
frame = tk.Frame(
master=test,
padx=1,
pady=1,
borderwidth=1
)
frame.grid(row=x(i), column=(i % 3))
button = tk.Button(
text=i,
master=frame,
width=10,
height=5,
bg="#333333",
fg="#ffffff",
command=print(i)
)
button.pack()
test.mainloop()
All functions with () will be executed immediately. Try to wrap your function print(i) into lambda function like that command=lambda _: print(i) and call it with command()

Python Tkinter error with button commands [duplicate]

This question already has answers here:
tkinter creating buttons in for loop passing command arguments
(3 answers)
Closed 5 years ago.
Hi I was trying to make simple calculator using tkinter gui with python.
But first of all I was trying to create buttons that once they are clicked, they were attached to the result shown on the screen. (Just as real-life calculator, if screen shows 12 and I click 3, the screen then shows 123)
from Tkinter import *
class Calculator(Frame):
def __init__(self):
Frame.__init__(self)
self.master.title('Calculator')
self.pack()
self.screen=Frame(self, borderwidth=20, relief=SUNKEN)
self.screen.pack()
self.txtDisplay = Text(self.screen, width=20, height=2)
self.txtDisplay.pack()
self.screen.grid(row=0, columnspan=5) #columnspan to span multiple columns
Contents = ['1','2','3','+','4','5','6','-','7','8','9','*','C','0','=','/']
Buttons = [None]*16
j=1
count=0
for i in range(16):
Buttons[i]=Button(self, text=Contents[i], command=lambda : self.txtDisplay.insert(END, Contents[i]), height=2, width=5, borderwidth=5)
Buttons[i].grid(row=j, column=i%4)
count+=1
if count%4==0:
j+=1
count=0
Calculator().mainloop()
However, the problem is the screen only attaches / whenever I click any button and eventually results in //////////////
/ is last element of Contents list and I guess there is something wrong with
command=lambda : self.txtDisplay.insert(END, Contents[i])
Can I get explanation on why this occurs and how I can deal with it?
Very problem problem with lambda in for loop. You can find many answers.
lambda doesn't use value from i when you create button but when you press button - so all buttons use the same value i which directs to last button.
You have to assign i to argument in lambda and it will copy value from i when you create button
command=lambda x=i: self.txtDisplay.insert(END, Contents[x])

How do I pass a index of a list to a callback of a button? [duplicate]

This question already has answers here:
tkinter creating buttons in for loop passing command arguments
(3 answers)
Closed 6 years ago.
I am writing a GUI using tkinter, and I have several lines consisting of a Entry widget inline with a Button widget. When I press the button, the callback opens the askdirectory dialog, and the directory choosen is written in the Entry widget, from the same line as the button clicked.
To get to a more elegant solution than just copy/paste 12 times the code, I wrote the following:
for i in range (0,12):
e[i] = Entry(master)
e[i].insert(0, "<Choose a directory...>")
e[i].config(width=70)
e[i].grid(row=i+2, column=0, sticky=NW, columnspan=2)
b[i] = Button(master, text="Choose directory", command=lambda: self.getDir(e[i]))
b[i].grid(row=i+2, column=2, sticky=N)
And the callback function:
def getDir(self, e):
'''Retrieve directory and write it on the right "Entry" widget'''
dirName = askdirectory(title='Choose a directory:')
e.delete(0, END)
e.insert(0, dirName)
When I run the script, I get the "list index out of range" error.
From my understanding, it is because i - which is used later on the code -, is not the index anymore, only in the moment I am building the buttons, right?
So, what should I do to make the callback understand which Button was clicked and to which Entry it should write?
I can only guess since you didn't post the error message:
could simply be the lenght of e and b! e and b need to be lists or tuples with at least the lenght of 12...or if you just want to process your code 12 times you dont need the [i] at all.
I would have posted this as a comment but I don't have enough points to do so :(

Tkinter Function attached to Button executed immediately [duplicate]

This question already has answers here:
How can I pass arguments to Tkinter button's callback command?
(2 answers)
Closed 6 years ago.
What I need is to attach a function to a button that is called with a parameter. When I write the code as below however, the code is executed once when the button is created and then no more. Also, the code works fine if I get rid of the parameter and parentheses when I declare the function as an attribute of the button. How can I call the function with a parameter only when the button is pressed?
from Tkinter import *
root =Tk()
def function(parameter):
print parameter
button = Button(root, text="Button", function=function('Test'))
button.pack()
root.mainloop()
The solution is to pass the function as a lambda:
from Tkinter import *
root =Tk()
def callback(parameter):
print parameter
button = Button(root, text="Button", command=lambda: callback(1))
button.pack()
root.mainloop()
Also, as #nbro already correctly pointed out, the button attribute is command, not function.

How do I get a button to display a label when clicked using tkinter? [duplicate]

This question already has answers here:
Why is my Button's command executed immediately when I create the Button, and not when I click it? [duplicate]
(5 answers)
Closed 7 years ago.
I want to make a button that displays a label when clicked. Here was my thinking:
from Tkinter import *
def write_hello():
w = Label(root, text = "Hello. This is a label.")
w.pack()
root = Tk()
button = Button(root, text = "Hello!", command = write_hello() )
button.pack()
root.mainloop()
Can anyone be nice enough to walk me through this? I'm very new.
You're calling the write_hello function before you even create the button, so what you're probably seeing is the label showing up before the button on the UI (and without clicking it). What you want to do is pass the function to the Button constructor instead of the function's return value:
button = Button(root, text = "Hello!", command = write_hello)

Categories