0

So in the following code I establish a Notebook in tkinter. I pull strings from the list VARS["IMPS"] and create pages with them in a dictionary using the strings as keys and the Frames as values.

My issue comes in when I establish the buttons, the function the button activates just prints the impname. However, when the application is built the while the labels always have the correct content in them and "impname". The buttons across all of the pages of the notebook always print the last string in the list VARS["IMPS"]. Why is this happening?

    Necromicon = ttk.Notebook(self)
    self.pages = {}
    for impname in __VARS__["IMPS"]:
        page = {}
        # Formate is Imp_acrobat.Imp()
        # impname is a string
        self.pages[impname] = page
        self.pages[impname]["Page"] = ttk.Frame(Necromicon)
        Necromicon.add(self.pages[impname]["Page"], text=impname[4:])
        x = ttk.Label(self.pages[impname]['Page'], text=impname)
        x.config(wraplength=175, font=SMALL_FONT)
        x.config(background='black', foreground='red')
        self.pages[impname]['Scroll'] = x
        self.pages[impname][impname + 'Button'] = tk.Button(
                self.pages[impname]['Page'],
                text='Activate',
                command=lambda: self.modload(self, controller, impname))
        self.pages[impname]['Scroll'].pack(fill="both", expand=True)
        self.pages[impname][impname + 'Button'].pack()
ForceBru
  • 43,482
  • 10
  • 63
  • 98
Hau5ratz
  • 35
  • 5

1 Answers1

0

To add to my previous answer, there is a Python FAQ about this issue.

Your statement

    self.pages[impname][impname + 'Button'] = tk.Button(
            self.pages[impname]['Page'],
            text='Activate',
            command=lambda: self.modload(self, controller, impname))

is equivalent to

    def button_command(): return self.modload(self, controller, impname))
    self.pages[impname][impname + 'Button'] = tk.Button(
            self.pages[impname]['Page'],
            text='Activate',
            command=button_command)

Does this make it any clearer that each button_handler() does the same thing? In fact, I would advise revising your code to

    def button_command(self=self, controller=controller, impname=impname):
        return self.modload(self, controller, impname))
    self.pages[impname][impname + 'Button'] = tk.Button(
            self.pages[impname]['Page'],
            text='Activate',
            command=button_command)

Now each button command is different because the default args are computed when the function is defined. I nearer always define button commands before creating buttons. Less confusing.

Terry Jan Reedy
  • 18,414
  • 3
  • 40
  • 52