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

Using the Menu.add_command() function in a for loop only uses the last iterable

This is kind of complicated to explain. So I am making a program that opens certain files in a directory. I want to achieve this by making the files options in a submenu within a Menu. The first half (adding the menu labels) does work, but the other half (adding the menu commands) does not.
In this case, the file opened is always ‘file3’ regardless of which file you choose via the submenu.
I expected for the ‘file1’ option to open ‘file1’ etc.

Here is the hypothetical code (which was simplified on purpose; hence the file opening is just a print function for the sake of debugging):

from tkinter import *
import os

root = Tk()

def openFile(file):
    print(file)

menubar = Menu(root, tearoff=0)

menubar_open = Menu(menubar, tearoff=0)

for i in ["file1", "file2", "file3"]:
    i = os.path.splitext(i)[0]
    menubar_open.add_command(label=i, command=lambda: openFile(file=i))

menubar.add_cascade(label="Open...", menu=menubar_open)

root.config(menu=menubar)

root.mainloop()

enter image description here

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

So the question is: What is causing this discrepancy and what can I do to solve it so it could open the file of its respective option?

>Solution :

You are actually almost there! Currently, when you are creating your lambda function, you do not provide the ‘i’ as input and so the interpreter uses the last ‘i’ globally known (which in your case is ‘file3’).

Therefore, if you define the input of the lambda at function creation (by which you effectively create a separate function/command per button) it works!

To make it work, you should change your .add_command line to:

menubar_open.add_command(label=i, command = lambda i = i : openFile(file=i))
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