0

I am new to python and encounter a problem with a small piece of code aiming at implementing a menu with Qt:

def setChoice(self,choice=None):
  do something here...

listOfChoices=[choice1,choice2,choice3]

menu=QMenu(self)
  for choice in listOfChoices:
    action=menu.addAction(choice)
    action.triggered.connect(lambda : self.setChoice(choice=choice))

The problem is that the setChoice() function is always called with choice=choice3, the last choice of the for loop. How to solve this problem properly ?

And a probably related question about immediate partial evaluation: How to save in memory f= lambda x : x+1 from a piece of code like a=1; f=lambda x: x+a ? Thanks for your explanations.

Denis

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
user3650925
  • 173
  • 1
  • 10

1 Answers1

4

This is a troublesome gotcha of Python for loops: the loop variable is created in the enclosing scope, and re-assigned for each iteration.

To get around this, you need to create a new local scope so that there is some place to "save" the variable:

for choice in listOfChoices:
    def act(choice):
        action=menu.addAction(choice)
        action.triggered.connect(lambda : self.setChoice(choice=choice))
    act(choice)

Or, in your second question,

def act(a):
    return lambda x: x + a
blah = act(1)
Owen
  • 38,836
  • 14
  • 95
  • 125