0

I have a for:loop which creates a tkinter menu cascade for every mailbox my email server has, all pointing to the same command, here's that code:

menubar = Menu (rootA)
    foldermenu = Menu(menubar, tearoff=0)
    for i in range(len(mailboxes)):
        foldermenu.add_command(label=mailboxes[i], command=switchBox)

But I need a way to identify exactly which button was clicked within my code, so is there any way to return the 'label' of the menu selection you just made or return an index or otherwise? for example the tkinter listbox has the function .curselection()

Imm
  • 37
  • 1
  • 7
  • Unrelated, but you can just use `command=switchBox`, without `lambda` and `()` – tobias_k Apr 25 '17 at 16:17
  • Oh yeah thanks! I was passing some variables through previously whilst trying to get this to work and must have forgotten to remove it. – Imm Apr 25 '17 at 16:18
  • Or you could pass the `i` to the lambda; in this case, remember that the variables in the lambda are evaluated when the function is called, not when it is defined (see e.g. [here](http://stackoverflow.com/q/19837486/1639625)), i.e. use something like `command=lambda x=i: switchBox(x)` – tobias_k Apr 25 '17 at 16:18

1 Answers1

3

You can pass the mail box to the callback. This is the main reason why you would want to use lambda. If you don't pass any values, there's no point in using lambda.

def switchBox(mailbox):
    ...

foldermenu.add_command(..., command=lambda mbox=mailboxes[i]: switchBox(mbox))
...

Note: this works because we are binding the value of mbox at the time the lambda is created. For more information about lambda and binding values, see What do (lambda) function closures capture?

Community
  • 1
  • 1
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • This is perfect! I'd been trying to do something similar but was always getting the last mailbox in the loop because of my formatting, thank you! – Imm Apr 25 '17 at 16:21