In general, the pieces of a widget are assembled using the idea of a cavity, an empty space that is to be filled with elements.
For example, in the classic
theme, a button has
four concentric elements. From the outside in, they are the
focus highlight, border, padding, and
label elements.
Each of these elements has a 'sticky'
attribute
that specifies how many of the four sides of the cavity it
“sticks” to. For example, if an element has a
sticky='ew'
attribute, that means it must
stretch in order to stick to the left (west) and right (east)
sides of its cavity, but it does not have to stretch
vertically.
Most of the built-in ttk styles use the idea of a
layout to organize the different
layers that make up a widget. Assuming that
is an instance of
S
ttk.Style
, to retrieve that style's layout
use a method call of this form, where
is the name of the
widget class.
widgetClass
S
.layout(widgetClass
)
Some widget classes don't have a layout; in those cases, this
method call will raise a tk.TclError
exception.
For the widget classes that have a layout, the returned
value is a list of tuples (
. Within each tuple, eltName
, d
)
is the name of an
element and eltName
is a dictionary that describes the element.
d
This dictionary may have values for the following keys:
'sticky'
A string that defines how this element is to be
positioned within its parent. This string may contain
zero or more of the characters 'n'
, 's'
, 'e'
, and 'w'
, referring to the sides of the box with the same
conventions as for anchors. For example, the value sticky='nsw'
would stretch this element to
adhere to the north, south, and west sides of the cavity
within its parent element.
'side'
For elements with multiple children, this value
defines how the element's children will be positioned
inside it. Values may be 'left'
,
'right'
, 'top'
, or
'bottom
.
'children'
If there are elements inside this element, this entry
in the dictionary is the layout of the child elements
using the same format as the top-level layout, that
is, a list of two-element tuples (
.
eltName
, d
)
Let's dissect the layout of the stock Button
widget of the 'classic'
theme in this
conversational example.
>>> import ttk >>> s = ttk.Style() >>> s.theme_use('classic') >>> b = ttk.Button(None, text='Yo') >>> bClass = b.winfo_class() >>> bClass 'TButton' >>> layout = s.layout('TButton') >>> layout [('Button.highlight', {'children': [('Button.border', {'border': '1', 'children': [('Button.padding', {'children': [('Button.label', {'sticky': 'nswe'})], 'sticky': 'nswe'})], 'sticky': 'nswe'})], 'sticky': 'nswe'})]
All those parentheses, brackets, and braces make that structure a bit hard to understand. Here it is in outline form:
The outermost element is the focus highlight; it has style
'Button.highlight'
. Its 'sticky'
attribute is 'nswe'
,
meaning it should expand in all four directions to fill
its cavity.
The only child of the focus highlight is the border
element, with style 'Button.border'
. It
has a 'border'
width of 1 pixel, and its
'sticky'
attribute also specifies that it
adheres to all four sides of its cavity, which is defined
by the inside of the highlight element.
Inside the border is a layer of padding, with style 'Button.padding'
. Its sticky
attribute also specifies that it fills its cavity.
Inside the padding layer is the text (or image, or both)
that appears on the button. Its style is 'Button.label'
, with the usual sticky='nswe'
attribute.
Each element has a dictionary of element
options that affect the appearance of that
element. The names of these options are all regular Tkinter
options such as 'anchor'
, 'justify'
, 'background'
, or 'highlightthickness'
.
To obtain the list of option names, use a method call of this
form, where
is
an instance of class S
ttk.Style
:
S
.element_options(styleName
)
The result is a sequence of option strings, each preceded by a
hyphen. Continuing our conversational above, where s
is an instance of ttk.Style
:
>>> d = s.element_options('Button.highlight') >>> d ('-highlightcolor', '-highlightthickness')
To find out what attributes are associated with an element option, use a method call of this form:
s
.lookup(layoutName
,optName
)
Continuing our example:
>>> s.lookup('Button.highlight', 'highlightthickness') 1 >>> s.lookup('Button.highlight', 'highlightcolor') '#d9d9d9' >>> print s.element_options('Button.label') ('-compound', '-space', '-text', '-font', '-foreground', '-underline', '-width', '-anchor', '-justify', '-wraplength', '-embossed', '-image', '-stipple', '-background') >>> s.lookup('Button.label', 'foreground') 'black'