Version 12 of ttk::style

Updated 2008-04-30 12:02:28 by LV

Introduction

A Ttk command that manipulates styles and themes. The information below refers to tile 0.8 and upwards.

Find the manual page for this command here:
http://tktable.sourceforge.net/tile/doc/style.html
http://www.tcl.tk/man/tcl8.5/TkCmd/ttk_style.htm


How do styles work?

A style is assigned to a Ttk widget and specifies the set of elements making up the widget and how they are arranged, along with dynamic and default settings for element options. This is from the manual page. What does this mean?

Let us take the statements one by one:

The style specifies the set of elements making up the widget

So, each widget is built using definable elements. A 'simple' label, for example, is made by using 3 different parts: a border element, a padding element, and the actual text of the label element. All three elements together form the ttk label widget.

How do we know what elements are used in the standard ttk widgets? This is what the command 'ttk::style layout' is for:

 % ttk::style layout TLabel
 Label.border -sticky nswe -border 1 -children {Label.padding -sticky nswe -border 1 -children {Label.label -sticky nswe}}

What you get is a description of the elements of the widget and how these elements are arranged (see next section). The words starting with the capital L are the elements: Label.border, Label.padding, and Label.label. How did we know to ask for TLabel in the above command? Well, the layout command requires a style name as an argument, and by default, the style name is the same as the widget's class name (this may be overridden by the -style option, if some code changes a widget). The class name is obtained by winfo class and you need to already have a widget created:

 % ttk::label .l
 % winfo class .l
 TLabel

If the widget already was changed by using the -style option, you can get the custom style name querying this option:

 % # assumng the custom style MyStyle.TLabel is already defined:
 % ttk::label .k -style MyStyle.TLabel
 % .k cget -style
 MyStyle.TLabel
 % # this would return the empty string, if the widget had no custom style

The style specifies how the elements are arranged

This is called the layout of the elements and we just saw it in the code above. The three elements mentioned above need to be arranged in a specific manner to look good and be useful. Let's take it again:

 % ttk::style layout TLabel
 Label.border -sticky nswe -border 1 -children {Label.padding -sticky nswe -border 1 -children {Label.label -sticky nswe}}

So, first comes the border and it sticks to the four corners of the space, which is assigned to the widget (-sticky nswe). The border has a border (funny, right?) of 1 (-border 1) and then it has some children. This means there is something inside the border. In our case, there is the second element inside: the padding. The padding is also sticky so it sticks to all four corners and it also has a border. The child of the padding is the actual label and the label also sticks to all four corners.

Now, children can be more than one element. The children option takes a list of elements, for example the scrollbar:

 % ttk::style layout Horizontal.TScrollbar
 Horizontal.Scrollbar.trough -sticky we -children {
     Horizontal.Scrollbar.leftarrow -side left -sticky {}
     Horizontal.Scrollbar.rightarrow -side right -sticky {}
     Horizontal.Scrollbar.thumb -expand 1 -sticky nswe
 }

The command does actually not return the layout formatted as above but this was done to see the individual elements of the last child in the horizontal scollbar widget.

The style specifies dynamic and default settings for element options

What font should the label use by default? Should the font change when the label is in different states (normal, disabled)? All this behaviour is defined by the style. The answers to these kind of questions is found using the ttk::style lookup command:

 % ttk::style lookup TLabel -font
 TkDefaultFont
 % ttk::style lookup TLabel -foreground
 black

This is but half the truth. The above command returns the values for the normal state. What about the 'disabled' state? Do this:

 % ttk::style lookup TLabel -foreground disabled
 #a3a3a3
 % ttk::style lookup TLabel -font disabled
 TkDefaultFont

So, in the disabled state, the font is the same, but the color is a gray shade.


Define your own style

[to be filled in]


How do I give a specific widget a specific color?

Suppose, you have a labelframe and want another foreground color for the label, say yellow. Since the label uses a sublayout to draw the actual label for the frame, you need to alter the configuration of TLabelframe.Label since this is the part of the layout that defines the label. Simply do:

 % ttk::style configure TLabelframe.Label -foreground yellow
 % ttk::labelframe .something
 % pack .something

See also [L1 ].


All this was taken from man pages and some threads on comp.lang.tcl: [L2 ], [L3 ]