How to set the variablee in a button command to own button's text in a loop that creates multipule buttons?
Question:
I have a loop that creates a button under a label that contains a list value:
def feed_page():
feed = ["Cooking", "Sports", "Tv", "Fashion"] #let's say those are the list's values
l = len(feed) - 1
x = 0
while l >=0:
Label(app, text=feed[l]).grid(row=x, column=1)
b = Button(app, text=feed[l])
b.configure(command=lambda: print_button_pressed_text(b.cget('text')))
b.grid(row=x+1, column=1)
x += 2
*The list Feed
length and values change every time the function feed_page()
is called.
I want that every time a certain button is pressed, the print_button_pressed_text
function will print out the text of that specific button that was pressed. (each button has his own unique number)
def print_button_pressed_text(num):
print num
However, no matter what button I press, the function prints the Value 'Fashion'
(the last value in the list..)
Do you have any idea what the problem is? and how can I fix it?
Answers:
def print_button_pressed_text(num):
def handler:
return num;
return handler;
UPD
The problem is that lambda functions look at the wrong button, only the last one since the loop doesn’t provide the right scope.
def make_button(text, row):
b = Button(app, text=text)
b.configure(command=lambda: print_button_pressed_text(b.cget('text')))
b.grid(row=x+1, column=1)
return b
while l >= 0:
make_button(feed[l], x + 1)
# ...
UPD2
Why does it happen? Please, check this out → https://louisabraham.github.io/articles/python-lambda-closures.html if you want to know more about scopes and closures.
Can’t you use the join function ?
Just define a function:
feed = ["Cooking", "Sports", "Tv", "Fashion"]
def print_the_list:
global feed
print(" ".join(feed))
print_the_list()
Then set this function as your button’s command. If you want to put , or ; or whatever you want between the elements, modify the ” ” into “,” or “;”
I have a loop that creates a button under a label that contains a list value:
def feed_page():
feed = ["Cooking", "Sports", "Tv", "Fashion"] #let's say those are the list's values
l = len(feed) - 1
x = 0
while l >=0:
Label(app, text=feed[l]).grid(row=x, column=1)
b = Button(app, text=feed[l])
b.configure(command=lambda: print_button_pressed_text(b.cget('text')))
b.grid(row=x+1, column=1)
x += 2
*The list Feed
length and values change every time the function feed_page()
is called.
I want that every time a certain button is pressed, the print_button_pressed_text
function will print out the text of that specific button that was pressed. (each button has his own unique number)
def print_button_pressed_text(num):
print num
However, no matter what button I press, the function prints the Value 'Fashion'
(the last value in the list..)
Do you have any idea what the problem is? and how can I fix it?
def print_button_pressed_text(num):
def handler:
return num;
return handler;
UPD
The problem is that lambda functions look at the wrong button, only the last one since the loop doesn’t provide the right scope.
def make_button(text, row):
b = Button(app, text=text)
b.configure(command=lambda: print_button_pressed_text(b.cget('text')))
b.grid(row=x+1, column=1)
return b
while l >= 0:
make_button(feed[l], x + 1)
# ...
UPD2
Why does it happen? Please, check this out → https://louisabraham.github.io/articles/python-lambda-closures.html if you want to know more about scopes and closures.
Can’t you use the join function ?
Just define a function:
feed = ["Cooking", "Sports", "Tv", "Fashion"]
def print_the_list:
global feed
print(" ".join(feed))
print_the_list()
Then set this function as your button’s command. If you want to put , or ; or whatever you want between the elements, modify the ” ” into “,” or “;”