'Tkinter buttons not changing back to the correct color after state changing to active

I am making this PDF tool, and I want the buttons to be disabled until a file or files are successfully imported. This is what the app looks like at the launch:Disabled State

Right after running the callback for the import files button, the active state looks like this: Active State

I want the colors of the buttons to turn maroon instead of the original grey. They only turn back to maroon once you hover the mouse over them. Any thoughts for how to fix this? Here is the callback for the import button:

def import_callback():
    no_files_selected = False
    global files
    files = []
    try:
        ocr_button['state'] = DISABLED
        merge_button['state'] = DISABLED
        status_label.pack_forget()
        frame.pack_forget()
        files = filedialog.askopenfilenames()
        for f in files:
            name, extension = os.path.splitext(f)
            if extension != '.pdf':
                raise
        if not files:
            no_files_selected = True
            raise

        if frame.winfo_children():
            for label in frame.winfo_children():
                label.destroy()
        make_import_file_labels(files)
        frame.pack()

        ocr_button['state'] = ACTIVE
        merge_button['state'] = ACTIVE
    except:
        if no_files_selected:
            status_label.config(text='No files selected.', fg='blue')
        else:
            status_label.config(text='Error: One or more files is not a PDF.', fg='red')
        status_label.pack(expand='yes')


import_button = Button(root, text='Import Files', width=scaled(20), bg='#5D1725', bd=0, fg='white', relief='groove',
                       command=import_callback)
import_button.pack(pady=scaled(50))


Solution 1:[1]

I know this was asked quite a while ago, so probably already solved for the user. But since I had the exact same problem and do not see the "simplest" answer here, I thought I would post:

Just change the state from "active" to "normal"

ocr_button['state'] = NORMAL
merge_button['state'] = NORMAL

I hope this helps future users!

Solution 2:[2]

I've wrote this simple app that I think could help all to reproduce the problem.

Notice that the state of the button when you click is Active.

#!/usr/bin/python3
import sys
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox

class Main(ttk.Frame):

    def __init__(self, parent, *args, **kwargs):
        super().__init__()


        self.parent = parent
        self.init_ui()

    def cols_configure(self, w):

        w.columnconfigure(0, weight=0,  minsize=100)
        w.columnconfigure(1, weight=0)
        
        w.rowconfigure(0, weight=0, minsize=50)
        w.rowconfigure(1, weight=0,)
        
        

    def get_init_ui(self, container):
        
        w = ttk.Frame(container, padding=5)
        self.cols_configure(w)
        w.grid(row=0, column=0, sticky=tk.N+tk.W+tk.S+tk.E)

        return w        
          
    def init_ui(self):

        w = self.get_init_ui(self.parent)

        r = 0
        c = 0
        
        b = ttk.LabelFrame(self.parent, text="", relief=tk.GROOVE, padding=5)
   
        self.btn_import = tk.Button(b,
                                    text="Import Files",
                                    underline=1,
                                    command = self.on_import,
                                    bg='#5D1725',
                                    bd=0,
                                    fg='white')
        self.btn_import.grid(row=r, column=c, sticky=tk.N+tk.W+tk.E,padx=5, pady=5)
          
        self.parent.bind("<Alt-i>", self.switch)

        r +=1

        self.btn_ocr = tk.Button(b,
                                    text="OCR FIles",
                                    underline=0,
                                    command = self.on_ocr,
                                    bg='#5D1725',
                                    bd=0,
                                    fg='white')

        self.btn_ocr["state"] = tk.DISABLED
        
        self.btn_ocr.grid(row=r, column=c, sticky=tk.N+tk.W+tk.E,padx=5, pady=5)

        r +=1

        self.btn_merge = tk.Button(b,
                                    text="Merge Files",
                                    underline=0,
                                    command = self.on_merge,
                                    bg='#5D1725',
                                    bd=0,
                                    fg='white')

        self.btn_merge["state"] = tk.DISABLED
        
        self.btn_merge.grid(row=r, column=c, sticky=tk.N+tk.W+tk.E,padx=5, pady=5)
          
        r +=1

        self.btn_reset = tk.Button(b,
                                    text="Reset",
                                    underline=0,
                                    command = self.switch,
                                    bg='#5D1725',
                                    bd=0,
                                    fg='white')
        self.btn_reset.grid(row=r, column=c, sticky=tk.N+tk.W+tk.E,padx=5, pady=5)
          
        
        b.grid(row=0, column=1, sticky=tk.N+tk.W+tk.S+tk.E)


    def on_import(self, evt=None):
        
        self.switch()
        #simulate some import
        self.after(5000, self.switch())
        
        
    def switch(self,):

        state = self.btn_import["state"]
        
        if state == tk.ACTIVE:
            self.btn_import["state"] = tk.DISABLED
            self.btn_ocr["state"] = tk.NORMAL
            self.btn_merge["state"] = tk.NORMAL
            
        else:
            self.btn_import["state"] = tk.NORMAL
            self.btn_ocr["state"] = tk.DISABLED
            self.btn_merge["state"] = tk.DISABLED
            
           
    def on_ocr(self, evt=None):
        state = self.btn_ocr["state"]
        print ("ocr button state is {0}".format(state))
        
        

    def on_merge(self, evt=None):
        state = self.btn_merge["state"]
        print ("merge button state is {0}".format(state))
        
        
    def on_close(self, evt=None):
        self.parent.on_exit()

class App(tk.Tk):
    """Main Application start here"""
    def __init__(self, *args, **kwargs):
        super().__init__()

        self.protocol("WM_DELETE_WINDOW", self.on_exit)
        self.set_style()
        self.set_title(kwargs['title'])
            
        
        Main(self, *args, **kwargs)
       
    def set_style(self):
        self.style = ttk.Style()
        #('winnative', 'clam', 'alt', 'default', 'classic', 'vista', 'xpnative')
        self.style.theme_use("clam")
        

    def set_title(self, title):
        s = "{0}".format('Simple App')
        self.title(s)
        
    def on_exit(self):
        """Close all"""
        if messagebox.askokcancel(self.title(), "Do you want to quit?", parent=self):
            self.destroy()

def main():

    args = []

    for i in sys.argv:
        args.append(i)

    kwargs = {"style":"clam", "title":"Simple App",}

    app = App(*args, **kwargs)

    app.mainloop()


if __name__ == '__main__':
    main()            
    

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 jwoods
Solution 2