TIP 584: Better introspection for ttk

Login
Author:         Francois Vogel <[email protected]>
State:          Final
Type:           Project
Vote:           Done
Vote-Summary:   Accepted 6/0/0
Votes-For:      MC, JD, DKF, FV, KW
Votes-Against:  none
Votes-Present:  none
Created:        24-Aug-2020
Post-History:   
Keywords:       Tk ttk introspection
Tcl-Version:    8.7
Tk-Branch:      ttk_introspect
Tk-Branch:      tip-584

Abstract

This TIP proposes to improve introspection capabilities of ttk.

Rationale

People regularly request (for instance in TkDocs, in TIP #555, or recently again in comp.lang.tcl) that ttk introspection capabilities be improved.

As it seems, the really missing bit is the ability to retrieve styles.

Specification

1. Obtaining all styles from a theme

A new subcommand

ttk::style theme styles ?themeName?

is created. It returns a list of all styles from themeName. If themeName is omitted, the current theme is used.

With this new command, the user can request all styles available in a given theme (or in the current theme). For example on Windows one can get:

    % ttk::style theme names
    winnative clam alt default classic vista xpnative
    % set curtheme [ttk::style theme use]
    vista
    % # leverage the new command ttk::style theme styles
    % ttk::style theme styles $curtheme
    Label TScale Horizontal.TScale TMenubutton TLabelframe.Label Vertical.TProgressbar TEntry TRadiobutton TButton Heading Toolbutton TNotebook.Tab ComboboxPopdownFrame Treeview Vertical.TScale TCombobox TNotebook TProgressbar Horizontal.TProgressbar . TCheckbutton Item TSpinbox Tab
    % ttk::style theme styles clam
    TMenubutton TEntry TLabelframe Vertical.Sash TRadiobutton Heading TButton TNotebook.Tab Toolbutton Treeview ComboboxPopdownFrame TCombobox TProgressbar . TCheckbutton Tab TSpinbox Horizontal.Sash Sash

Then it becomes straightforward to get all layouts, as originally requested in TIP #555:

    # get layout for each style
    foreach st [ttk::style theme styles] {
        if {[catch {ttk::style layout $st}]} {
            puts "$st: has no layout"
        } else {
            puts "$st:\n[ttk::style layout $st]"
        }
    }

This spits:

    Label:
    Label.fill -sticky nswe -children {Label.text -sticky nswe}
    TScale: has no layout
    Horizontal.TScale:
    Scale.focus -sticky nswe -children {Horizontal.Scale.trough -sticky nswe -children {Horizontal.Scale.track -sticky we Horizontal.Scale.slider -side left -sticky {}}}
    <...and so on...> 

2. Obtaining the style used by a given ttk widget

A new subcommand

.pathname style

is created. It returns the style actually used by any ttk widget .pathname. This new command is added as a standard widget command (documented in ttk_widget(n)).

Examples of use:

    % ttk::scrollbar .sv  ; # default orient is vertical
    .sv
    % .sv style
    Vertical.TScrollbar
    %
    % ttk::scrollbar .sh -orient horizontal
    .sh
    % .sh style
    Horizontal.TScrollbar
    %
    % ttk::style configure style1.TButton -background yellow
    % ttk::button .b -style style1.TButton
    .b
    % .b style
    style1.TButton

Note that this new style command is different from getting the -style option of the widget since [.pathname cget -style] returns the empty string if .pathname uses the default style of the widget.

Also, this is not the same as the widget class that one can get through [winfo class .pathname].

Implementation

See the ttk_introspect branch, aka tip-584.

This branch targets 8.7.

Copyright

This document has been placed in the public domain.