Disabling tkinter ttk scale widget

4.4k views Asked by At

I am trying to disable all of the (ttk) widgets in a frame, but it appears that the scale widget is giving me some trouble, as it throws the following exception:

_tkinter.TclError: unknown option "-state"

Some relevant code:

import tkinter as tk
from tkinter import ttk

def disable_widgets(parent):
    for child in parent.winfo_children():
        child.config(state = 'disabled')

root = tk.Tk()

# Frame full of widgets to toggle
frame_of_widgets = ttk.Frame(root)
frame_of_widgets.pack()

# Button to be disabled
button_to_disable = ttk.Button(frame_of_widgets)
button_to_disable.pack()

# Entry to be disabled
entry_to_disable = ttk.Entry(frame_of_widgets)
entry_to_disable.pack()

# Scale to be disabled
scale_to_disable = ttk.Scale(frame_of_widgets)
scale_to_disable.pack()

# Button that disables widgets in frame
disable_button = ttk.Button(root,text="Disable",command= lambda: disable_widgets(frame_of_widgets))
disable_button.pack()

root.mainloop()

It works for the button and entry, but not for the scale. I thought one of the benefits of ttk was making widgets more uniform with common methods and attributes, so I am guessing perhaps I am accessing all three of these widgets incorrectly?

2

There are 2 answers

1
Bryan Oakley On BEST ANSWER

For ttk widgets you use the state method. The state method for buttons and entry widgets are just a convenience function to mimic the standard button and entry widgets.

You can rewrite your function like this:

def disable_widgets(parent):
    for child in parent.winfo_children():
        child.state(["disabled"])

ttk states are mentioned in the ttk documentation here (though the description borders on useless): https://docs.python.org/3.1/library/tkinter.ttk.html#widget-states

4
Carson On

another way:

scale_to_disable.configure(state='disabled')  # 'normal'

You can consider that set the breakpoint at the configure of the class Scale (from tkinter.ttk import Scale) may get some helpful.

The following is part of the code to intercept the class Scale

class Scale(Widget, tkinter.Scale):

    ...

    def configure(self, cnf=None, **kw):
        if cnf:
            kw.update(cnf)
        Widget.configure(self, **kw)