-1

I am not experienced programmer and I could not find a solution for this problem. I would like to create a long list of subroutines with their button description and use the code below to create the buttons. But such code assigns always last subroutine from the list to all buttons.

self.row=Frame(root)
self.programs=(('description1',p1),('description2',p2))
for self.program in self.programs:
    self.b= Button(self.row, text=self.program[0], command=lambda event="":self.program[1]())
    self.row.pack(side=TOP, fill=X, padx=5, pady=5)
    self.b.pack(side=LEFT, padx=5, pady=5)

It runs fine except all buttons are executing p2. How to solve that?

Thank you.

1 Answers1

0

It's because of late binding, the self.program is determine when the callback is called, not when it is created.

Use default parameter to avoid the problem:

self.row=Frame(root)
self.programs=(('description1',p1),('description2',p2))
for naem, callback in self.programs:
    self.b = Button(self.row, text=self.program[0],
                    command=lambda callback=callback: callback())  # <---
    self.row.pack(side=TOP, fill=X, padx=5, pady=5)
    self.b.pack(side=LEFT, padx=5, pady=5)

BTW, the callback set using command does not called with an argument.

falsetru
  • 357,413
  • 63
  • 732
  • 636