Python: toggle a button (adding more buttons)
Question: This is just the initial code for what will be an array of buttons, effecting
each other. I can't seen to understand why I keep getting this definition
error!

    
    
    from tkinter import *
    import tkinter.messagebox
    from tkinter import ttk
    
    
    def changeImage(Num):
        global buttonOn
        global buttonOff
        if Num == 1:
            if button1(image) == buttonOn:
                button1.config(image=buttonOff)
            else:
                button1.config(image=buttonOn)
    
    root = Tk()
    
    root.geometry('155x190')
    root.title("Tile Turner")
    
    buttonOn = PhotoImage(file="buttonPic.gif")
    buttonOff = PhotoImage(file="buttonPic2.gif")
    
    button1 = Button(image=buttonOn, width=20, height=20, command=changeImage(1))
    buttonQuit = Button(text="Quit", width=10, height=0, command=root.destroy)
    
    
    app.grid(column=0, row=0)
    button1.grid(column=2, row = 3)
    buttonQuit.grid(column=3, row = 10, columnspan = 4)
    
    root.mainloop()
    

My definition error is in button1:

    
    
    Traceback (most recent call last):
      File "C:/Users/Jimmy/Desktop/COS 2013/Game1/small", line 23, in <module>
        button1 = Button(image=buttonOn, width=20, height=20, command=changeImage(1))
      File "C:/Users/Jimmy/Desktop/COS 2013/Game1/small", line 10, in changeImage
        if button1(image) == buttonOn:
    NameError: global name 'button1' is not defined
    

Any help at all would be appreciated!


Answer: In this line,

    
    
    button1 = Button(image=buttonOn, width=20, height=20, command=changeImage(1))
    

You call the function `changeImage` passing in `1` as the argument. That
function then gets evaluated and the _result_ (`None` in this case) gets
passed to the `command=...` default argument of the `Button` constructor. Of
course, this causes you to get the `NameError` because you call `changeImage`
before you actually pass it to the Button constructor -- i.e. `button1`
doesn't exist yet because it is waiting for the `changeImage` function to
finish before it can continue on with constructing the `Button` instance.

You want something like:

    
    
    button1 = Button(...,command=lambda:changeImage(1))
    

This creates a new function which when called simply calls `changeImage` with
the proper argument.

To elaborate a little further on lambda, the above statement is more or less
shorthand for

    
    
    def temp_function():
        return changeImage(1)
    
    button1 = Button(...,command=temp_function)
    

