Question

What I am trying to do here is add the image to the button I have, then based on click or hover change the image. All the examples I have followed use the .config() method.

For the life of me I can't figure out why it doesn't know what the button object is. What is interesting is that if I modify the Button definition line to include the image option, everything is fine. But, with that there it seems I can't modify it using .config()

PlayUp = PhotoImage(file=currentdir+'\Up_image.gif')
PlayDown = PhotoImage(file=currentdir+'\Down_image.gif')
#Functions
def playButton():
    pButton.config(image=PlayDown)
pButton = Button(root, text="Play", command="playButton").grid(row=1)
pButton.config(image=PlayUp)
Was it helpful?

Solution

pButton = Button(root, text="Play", command="playButton").grid(row=1)

Here you are creating an object of type Button, but you are immediately calling the grid method over it, which returns None. Thus, pButton gets assigned None, and that's why the next row fails.

You should do instead:

pButton = Button(root, text="Play", command="playButton")
pButton.grid(row=1)
pButton.config(image=PlayUp)

i.e. first you create the button and assign it to pButton, then you do stuff over it.

OTHER TIPS

I do not know if it helps in similar cases:

mywidget = Tkinter.Entry(root,textvariable=myvar,width=10).pack()
mywidget.config(bg='red')

This generates this error:

AttributeError: 'NoneType' object has no attribute 'config'

But everythings run smoothly if I write on separate lines:

mywidget = Tkinter.Entry(root,textvariable=myvar,width=10)
mywidget.pack()
mywidget.config(bg='red')

I do not understand it but it took me a lot of time to solve... :-(

canvas = tk.Tk()
canvas.title("Text Entry")

text_label = ttk.Label(canvas, text = "Default Text")
text_label_1 = ttk.Label(canvas, text = "Enter Your Name: ").grid(column = 0, row = 1)
text_variable = tk.StringVar()
text_entry = ttk.Entry(canvas, width = 15, textvariable = text_variable)
text_entry.grid(column = 1, row = 1)
def change_greeting():
    text_label.configure(text = "Hello " + text_variable.get())
event_button = ttk.Button(canvas, text="Click me and see what happens", command = change_greeting).grid(column = 2, row = 1)
text_label.grid(column = 0, row = 0)
canvas.resizable(False, False)
canvas.mainloop()

In the above code text_label.grid(column = 0, row = 0) is placed at the end that is after all the operations on the label is completed.
If text_label = ttk.Label(canvas, text = "Default Text").grid(column = 0, row = 0) is done in the above code then the error will be produced. Hence being cautious about the display of objects is necessary

Yes, I have found that packing using one-liners such as btt = Button(root,text='Hi Button').pack()

have been messing with the object data type for example setting it to NoneType but if you use .pack after like this btt.pack() this will mitigate most issues related to tkinter.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top