pythontkinter

Changing button's look by state; Only works while debugging


For some background, I'm displaying my button as an image. What I want to change the look of my button when it's clicked and keep it as that new look until it is clicked again. Here's what I have so far:

from tkinter import *
from tkinter import ttk
 
def TestLogic():
    print(testBtn["state"])
    if testBtn["state"] == "normal":
        stgImg = PhotoImage(file="test1.png")
        testBtn.configure(image=stgImg)
        testBtn.image = stgImg
        testBtn.configure(state="active")
    elif testBtn["state"] == "active":
        stgImg = PhotoImage(file="test.png")
        testBtn.configure(image=stgImg)
        testBtn.image = stgImg
        testBtn.configure(state="normal")
 
root = Tk()
 
root.geometry('600x600')
  
stgImg = PhotoImage(file="test.png")  
testBtn=ttk.Button(root, text="TEST", image = stgImg, command=TestLogic)
testBtn.pack(anchor="center")
root.mainloop()

The problem is that without the print statement the code doesn't work, however, it works just fine with the print statement. I want to know why, how to fix this issue so I don't have to have the print statement, and possibly some ideas on how to improve this.


Solution

  • The problem is in your if conditions.

    testBtn['state'] is NOT a string, printing type(testBtn['state']) actually gives <class '_tkinter.Tcl_Obj'>

    The reason that testBtn['state'] is not a string is because you are using ttk.Button() and not using tk.Button() (Button() in your case since you are importing all from Tkinter)

    This will work if you change your if conditions to this:

    if str(testBtn["state"]) == "normal":
            stgImg = PhotoImage(file="test1.png")
            testBtn.configure(image=stgImg)
            testBtn.image = stgImg
            testBtn.configure(state="active")
    elif str(testBtn["state"]) == "active":
            stgImg = PhotoImage(file="test.png")
            testBtn.configure(image=stgImg)
            testBtn.image = stgImg
            testBtn.configure(state="normal")
    

    Check this for more information:

    Check state of button in tkinter