Is there a way to gray out (disable) a tkinter Frame? Is there a way to gray out (disable) a tkinter Frame? tkinter tkinter

Is there a way to gray out (disable) a tkinter Frame?


Not sure how elegant it is, but I found a solution by adding

for child in frame2.winfo_children():    child.configure(state='disable')

which loops through and disables each of frame2's children, and by changing enable() to essentially reverse this with

def enable(childList):    for child in childList:        child.configure(state='enable')

Furthermore, I removed frame2.state(statespec='disabled') as this doesn't do what I need and throws an error besides.

Here's the complete code:

from tkinter import *from tkinter import ttkdef enable(childList):    for child in childList:        child.configure(state='enable')root = Tk()#Creates top frameframe1 = ttk.LabelFrame(root, padding=(10,10,10,10))frame1.grid(column=0, row=0, padx=10, pady=10)button2 = ttk.Button(frame1, text="This enables bottom frame",                      command=lambda: enable(frame2.winfo_children()))button2.pack()#Creates bottom frameframe2 = ttk.LabelFrame(root, padding=(10,10,10,10))frame2.grid(column=0, row=1, padx=10, pady=10)entry = ttk.Entry(frame2)entry.pack()button2 = ttk.Button(frame2, text="button")button2.pack()for child in frame2.winfo_children():    child.configure(state='disable')root.mainloop()


Based on @big Sharpie solution here are 2 generic functions that can disable and enable back a hierarchy of widget (frames "included"). Frame do not support the state setter.

def disableChildren(parent):    for child in parent.winfo_children():        wtype = child.winfo_class()        if wtype not in ('Frame','Labelframe'):            child.configure(state='disable')        else:            disableChildren(child)def enableChildren(parent):    for child in parent.winfo_children():        wtype = child.winfo_class()        print (wtype)        if wtype not in ('Frame','Labelframe'):            child.configure(state='normal')        else:            enableChildren(child)


I think you can simply hide the whole frame at once.If used grid

 frame2.grid_forget()

If used pack

 frame2.pack_forget()

In your case the function would be

 def disable():     frame2.pack_forget()

To enable again

def enable():    frame2.pack()

grid_forget() or pack_forget() can be used for almost all tkinter widgetsthis is a simple way and reduces the length of your code, I'm sure it works