Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is there a way to identify a specific pressed button created in a list? (tkinter)

I have created a variable-length list containing several buttons:

buttonList = [tk.Button(command=record,
                        text=str((i % MONTH_LEN[TIME.month]) + 1))
              for i in range(x)]

x is the length of the list of buttons (PREDEFINED!).

MONTH_LEN and TIME.MONTH shouldn’t be needed of course; they’re just part of the text.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I want to be able to differentiate between the different buttons being clicked WITHOUT needing to create masses of functions.

The most important part to note is that record should change a character in a string based on which button was clicked; the first button changes the first element in the string, the 20th button changes the 20th element in the string etc etc.

How can I achieve this? Is there a better way to go about this?

>Solution :

Use lambda functions

Here is an example:

import tkinter as tk

root = tk.Tk()

x = 20

my_list = ['a'] * x

def record(index):
    my_list[index] = 'b'
    print(''.join(my_list))

buttonList = [
    tk.Button(
        command=lambda index=i: record(index),
        text=str(i),
        )
    for i in range(x)
    ]

for button in buttonList:
    button.pack()

root.mainloop()

lambdas are a way to create "masses of functions" (as you put it) on the fly, without needing to give them names. The code lambda index=i: record(index) is pretty much equivalent to the following code:

def noname(index=i):
    return record(index)

Note that we have to create a keyword argument index and set its default value to i in order to "capture" the value of i at each loop iteration. If we instead did lambda: record(i), it would look up the value of i in the global scope, which will be equal to its value on the last iteration.

Errata

record should change a character in a string based on which button was clicked

Python strings are not mutable, unlike in many other languages. You cannot change them element-by-element. Actually, you cannot change them at all. You have to use a mutable container like list, and convert it to a string, as I did in my example.

Also, consider renaming buttonList to button_list. Using underscores is the convention in Python. You can read more about variable naming in PEP8.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading