0

Premise:

I'm creating a little wx.Frame were i have a wx.SubMenu with a variable number of wx.MenuItems, and i want to bind they to a method, so i used this code:

self.selectworkout = wx.Menu()
self.x = 110
y = []
for elem in self.workout_list:
    y.append(self.selectworkout.Append(int(self.x), elem.title, elem.title + " | " + elem.description))
    index = self.workout_list.index(elem)
    self.Bind(wx.EVT_MENU, lambda event: self.OnSelectWorkout(event, elem), y[index])
    self.x+=1

to have a pointer to the wx.MenuItems, i stored them in a list and then i bind they using the corrispondent list item

Issue:

The problem is that when i click them, the call the method but they pass the same parameters, like if i have been bindin the same wx.MenuItem

Question:

Do you know where th problem is or what is the optimal way to do what i need?

Leonardo Scotti
  • 1,069
  • 8
  • 21
  • You could simply try to use `y[-1]` to retrieve the last appended MenuItem for Bind. – Michael Butscher Dec 13 '20 at 10:53
  • i know what is it, and it seems thaht iwhen a cliak one, i always click the last, but the problem is how can i do to bind every so when i click one it is passed like argument? – Leonardo Scotti Dec 13 '20 at 11:06

1 Answers1

1

The problem with

self.Bind(wx.EVT_MENU, lambda event: self.OnSelectWorkout(event, elem), y[index])

is that the elem in the lambda expression is actually the variable from the surrounding function. If it is changed by the for-loop it is changed for all created lambdas.

Simple solution: Change it to:

self.Bind(wx.EVT_MENU, lambda event, elem=elem: self.OnSelectWorkout(event, elem), y[index])
Michael Butscher
  • 10,028
  • 4
  • 24
  • 25