1

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?

  • Can you show me the function u use to change the button's text? I mean the function `print_button_pressed_text` – Daniyal Ahmad Apr 17 '20 at 13:08
  • I can't say that it will fix your problem because I haven't seen the other function yet... I found one simple problem this far... to solve it use `lambda`... like this:`b.configure(command=lambda: print_button_pressed_text(b.cget('text')))` – Daniyal Ahmad Apr 17 '20 at 13:11
  • @DaniyalAhmad this function doesn't change the button's text, it simply prints the text she's given : `def print_button_pressed_text(num): print num` – mimi quarantine Apr 17 '20 at 13:12
  • @DaniyalAhmad I used Lambda and that's the result it printed out. I forgot to add it in my question. – mimi quarantine Apr 17 '20 at 13:14

2 Answers2

1
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.

vitkarpov
  • 354
  • 2
  • 8
0

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 ";"

Quantum Sushi
  • 444
  • 6
  • 18
  • hey, @TheMachinist, I want to know which button was pressed, how can I do that? (this will change values in a sqlite3 database table I have) – mimi quarantine Apr 17 '20 at 13:18
  • Can you be more specific ? I mean, what do you mean by knowing wich button was pressed ? As I understand it it is pretty simple, just do a function for each button and when the button is pressed it puts 1 or 2 or I don't know what into a variable :/ – Quantum Sushi Apr 17 '20 at 13:21
  • The problem is I have a lot of buttons, and I don't how many buttons I have each time. (because the list's length changes every time the `feed_page()` is called) so I can't create a function for each button @TheMachinist (I can't know how many functions to create) – mimi quarantine Apr 17 '20 at 13:25
  • Oh ok I understand your problem... https://stackoverflow.com/questions/26765218/get-the-text-of-a-button-widget ;) – Quantum Sushi Apr 17 '20 at 13:35