Element names use a recursive dotted notation. For example, uparrow identifies a generic arrow element, and Scrollbar.uparrow and Combobox.uparrow identify widget-specific elements. When looking for an element, the style engine looks for the specific name first, and if an element of that name is not found it looks for generic elements by stripping off successive leading components of the element name.
Like widgets, elements have options which specify what to display and how to display it. For example, the text element (which displays a text string) has -text, -font, -foreground, -background, -underline, and -width options. The value of an element option is taken from (in precedence order):
ttk::style layout Horizontal.TScrollbar { Scrollbar.trough -children { Scrollbar.leftarrow -side left -sticky w Scrollbar.rightarrow -side right -sticky e Scrollbar.thumb -sticky ew } }
By default, the layout for a widget is the same as its class name. Some widgets may override this (for example, the ttk::scrollbar widget chooses different layouts based on the -orient option).
The themed Tk widgets generalizes this idea: every widget has a bitmap of independent state flags. Widget state flags include active, disabled, pressed, focus, etc., (see ttk::widget(n) for the full list of state flags).
Instead of a -state option, every widget now has a state widget command which is used to set or query the state. A state specification is a list of symbolic state names indicating which bits are set, each optionally prefixed with an exclamation point indicating that the bit is cleared instead.
For example, the class bindings for the ttk::button widget are:
bind TButton <Enter> { %W state active } bind TButton <Leave> { %W state !active } bind TButton <ButtonPress-1> { %W state pressed } bind TButton <Button1-Leave> { %W state !pressed } bind TButton <Button1-Enter> { %W state pressed } bind TButton <ButtonRelease-1> \ { %W instate {pressed} { %W state !pressed ; %W invoke } }
This specifies that the widget becomes active when the pointer enters the widget, and inactive when it leaves. Similarly it becomes pressed when the mouse button is pressed, and !pressed on the ButtonRelease event. In addition, the button unpresses if pointer is dragged outside the widget while Button-1 is held down, and represses if it's dragged back in. Finally, when the mouse button is released, the widget's -command is invoked, but only if the button is currently in the pressed state. (The actual bindings are a little more complicated than the above, but not by much).
ttk::style configure TButton \ -background #d9d9d9 \ -foreground black \ -relief raised \ ;
Many elements are displayed differently depending on the widget state. For example, buttons have a different background when they are active, a different foreground when disabled, and a different relief when pressed. The style map command specifies dynamic option settings for a particular style:
ttk::style map TButton \ -background [list disabled #d9d9d9 active #ececec] \ -foreground [list disabled #a3a3a3] \ -relief [list {pressed !disabled} sunken] \ ;