0

My question relates to tkinter. I am creating a GUI in which there are 31 different buttons with a different logo on each button. Here is how I create those buttons in the main window:

logos = ['ducks.png', 'bruins.png', 'sabres.png', 'flames.png', 'canes.png', 'hawks.png', 'avs.png',
         'jackets.png', 'stars.png', 'redwings.png', 'oilers.png', 'panthers.png', 'kings.png',
         'wild.png', 'habs.png', 'preds.png', 'devils.png', 'isles.png', 'rangers.png', 'sens.png',
         'flyers.png', 'yotes.png', 'pens.png', 'blues.png', 'sharks.png', 'bolts.png', 'leafs.png',
         'canucks.png', 'knights.png', 'caps.png', 'jets.png']

for logo in logos:
    load = Image.open(logo)
    render = ImageTk.PhotoImage(load)
    teamButton = Button(self, image=render)
    teamButton.image = render
    teamButton.place(x=x_axis, y=y_axis)
    x_axis += 80
    if x_axis >= 300:
        y_axis += 55
        x_axis = 0

What I am trying to do:

  • When user clicks certain button for example "ducks" the program prints a value, let's say 3.
  • Then, when user clicks another button for example "Bruins" the program prints value 2.

My questions are:

  1. How do I bind the button Ducks with value 3 and the button Bruins with value
  2. And is this the best way (for loop) to create these type of buttons? If it's not, what is?
martineau
  • 119,623
  • 25
  • 170
  • 301
jondej
  • 13
  • 3

1 Answers1

1

Use functools.partial to make functions on the fly.

from functools import partial

for value, logo in enumerate(logos):
    # not sure where this value is coming from ... so used enumerate for now
    load = Image.open(logo)
    render = ImageTk.PhotoImage(load)
    teamButton = Button(self, image=render)
    teamButton.image = render
    teamButton.config(command=partial(print, value))
    teamButton.place(x=x_axis, y=y_axis)
Novel
  • 13,406
  • 2
  • 25
  • 41
  • [`partial()`](https://docs.python.org/3/library/functools.html#functools.partial) doesn't make functions, it make "partial" objects the behave like functions that pass the original function some or all of the arguments it requires automatically. Other than that nit-pick, your answer is correct (and good advice) IMO. – martineau Dec 28 '20 at 21:02
  • Thank you! That's a start at least... You see, values 2 and 3 that I used in my question were literally just examples and I am quite happy with this result already.To solve my REAL problem: I need to bind let's say Button #1 to get the value from an xlsx-file, column A1. So I quess what I am trying to do is to bind this button click as an user input that collects certain value from an excel file... – jondej Dec 28 '20 at 21:22
  • @JoonasJunttila ok, so make a function that does whatever you want to do, and use that as `command=partial(my_function, logo)` or whatever you want to use as the value. – Novel Dec 28 '20 at 21:47