Definitions
Widget Class
A widget class is used by Tk to identify the type of a particular widget; essentially, whether it is a button, a label, a canvas, etc. In classic Tk, all buttons had the same class ("Button"), all labels had the same class ("Label"), etc.
There were a few classic Tk widgets, including frame and toplevel widgets, which would allow you to change the widget class of a particular widget when the widget was first created, by passing it a "class" configuration option. So while normally frames would have a widget class of "Frame", you could specify that one particular frame widget had a widget class of "SpecialFrame".
Because of that, you could use the option database to define different looks for different types of frame widgets (not just all frame widgets, or frame widgets located at a particular place in the hierarchy).
Widget State
A
widget state allows a single widget to have more than one appearance or behaviour, depending on things like mouse position, different state options set by the application, and so on.
Style
Very simply, a style describes the appearance (or appearances) of a Ttk widget class.
Themes
You can think of a theme as a collection of styles. While each style is widget-specific (one for buttons, one for entries, etc.) a theme will collect many styles together.
Using Styles and Themes
Style Names
If you have a particular widget, and you want to know what style it is currently using, you can first check the value of its "style" configuration option. If that is empty, it means the widget is using the default style for the widget. You can retrieve that via the widget's class. For example:
>>> b = ttk.Button()
>>> b['style']
''
>>> b.winfo_class()
'TButton'
Using a Style
b = ttk.Button(parent, text='Hello', style='Fun.TButton')
As well, you can change the style of a widget at anytime after you've created it with the
"style"configuration option:
b['style'] = 'NuclearReactor.TButton'
Using Themes
While styles control the appearance of individual widgets, themes control the appearance of the entire user interface. The ability to switch between themes is one of the significant features of the themed widgets.
You can obtain the names of all available themes:
>>> s = ttk.Style()
>>> s.theme_names()
('aqua', 'step', 'clam', 'alt', 'default', 'classic')
Only one theme can ever be active at a time. To obtain the name of the theme currently in use, you can use the following:
>>> s.theme_use()
'aqua'
Switching to a new theme can be done with:
s.theme_use('themename')
What's Inside a Style?
Elements
While each style represents a single widget, each widget is normally composed of smaller pieces, called elements.
Layout
We can ask Tk what the layout of the TButton style is like this:
>>> s.layout('TButton')
[("Button.border", {"children": [("Button.focus", {"children": [("Button.spacing",
{"children": [("Button.label", {"sticky": "nswe"})], "sticky": "nswe"})],
"sticky": "nswe"})], "sticky": "nswe", "border": "1"})]
Element Options
What options are available for each element? Here's an example of checking what options are available for the label inside the button (which we know from the "layout" command is identified as "Button.label"):
>>> s.element_options('Button.label')
('-compound', '-space', '-text', '-font', '-foreground', '-underline', '-width', '-anchor', '-justify',
'-wraplength', '-embossed', '-image', '-stipple', '-background')
Changing Style Options
Modifying a Style Option
Modifying a configuration option for an existing style is done in a similar fashion as modifying any other configuration option, by specifying the style, name of the option, and new value:
s.configure('TButton', font='helvetica 24')
If you need to retrieve the current value of an option, this can be done with the
"lookup" method.
>>> s.lookup('TButton', 'font')
'helvetica 24'
Creating a New, Derived Style
If you modify an existing style, such as "TButton", that modification will apply to all widgets using that style (so by default, all buttons). That may well be what you want to do.
s.configure('Emergency.TButton', font='helvetica 24',
foreground='red', padding=10)
State Specific Style Options
The following example provides for the following variations from a button's "normal" appearance:
- when the widget is in the disabled state, the background color should be set to "#d9d9d9"
- when the widget is in the active state (mouse over it), the background color should be set to "#ececec"
- when the widget is in the disabled state, the foreground color should be set to "#a3a3a3" (this is in addition to the background color change we already noted)
- when the widget is in the state where the button is pressed and the widget is not disabled, the relief should be set to "sunken"