0

What I need, is a menu in tkinter, where each item has the name of a playlist, and each item will go to the same function (ImportPlaylist()) , but passes a different variable, namely: the rownumber for a csv file where that playlist is stored.

This cannot be done just by hand, because it happens dynamically, i.e. the user can make his own set of playlist with his own names.

I have made a music player, and am just experimenting now with reading and writing csv files. I made a csv file, and made a function to save playlists to that csv file. The way they are saved is that in each row, the first item is the name of the playlist, after that come youtube links one by one.

What I want is now to have functions for importing the playlists. The functions should be called from a tkinter menu. So they need to be created at the opening of the program. I was hoping to do this with a for-loop. So, the for loop would go through the csv file row by row, and for every row create a menu-item, whose name is the first item in the row, and who refers to a function ImportPlaylist, passing some argument to indicate from which row the playlist needs to be imported. Is this even possible?

To import a playlist, I made this little bit of code, generating menu items in a tkinter window:

with open(os.path.join(sys.path[0], "AntiTubePlaylists.txt"), "r") as csv_file:
    csv_reader = csv.reader(csv_file, quotechar='"', delimiter=',')
    counter = 0
    for row in csv_reader:
        playlistmenu.add_command(label=row[0], command=(lambda:  ImportPlaylist(counter)))
        counter += 1

This doesn't work. Which I kind of understand. I suppose counter is a global variable, and therefor all my nicely generated menu items refer to the same number, which is an empty row.

Any thoughts on this?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
  • This isn't very clear, but I think you're looking for [this](https://stackoverflow.com/questions/233673/how-do-lexical-closures-work). – Carcigenicate Dec 24 '22 at 22:56
  • Thank you. The link you give Probably provides me the resources to do what I want. It's a bit of a different take on the problem, but one that works (I think). If I can make it work, I will provide the solution – Willem van Houten Dec 24 '22 at 23:20
  • On second thought: that solution shows me how to make many functions; but how do I access the function I want? I think that it realy doesnt solve my problem.. What I need is a whole bunch of menu items that each call the same function, but giving different arguments. – Willem van Houten Dec 24 '22 at 23:25
  • "but how do I access the function I want?" By... using the corresponding command in the `playlistmenu`? The entire point of calling `.add_command` is that **Tkinter keeps track of the function for you**, associating it with a specific command, and calls it when the corresponding UI action is taken. – Karl Knechtel Dec 24 '22 at 23:33
  • "What I need is a whole bunch of menu items that each call the same function, but giving different arguments." Yes; that's what you get using the described approach (I closed the question with some more specific duplicates). Tkinter can't pass arguments to your functions at all, because it doesn't have any way to know what to pass. That's the purpose of the attempt using`lambda`: to specify those values ahead of time. However, it doesn't work here due to **late binding**, as described and addressed in the duplicates. – Karl Knechtel Dec 24 '22 at 23:35

0 Answers0