Tutorial: Modifying a ttk button's style

bll 2018-1-2 Per request, adding the answer from StackOverflow to the wiki. This tutorial shows how to modify a ttk::button to add a image into the upper right corner. In the original use case the user was already using images in their button, and also wanted to add an indicator to the button to indicate the context of the action.

img-tutorial-modifying-ttk-button-style

First you need the images:

set imgred [image create photo -file redcorner.png]
set imggreen [image create photo -file greencorner.png]

Next create a style element for each of these colors:

ttk::style element create Red.Corner.TButton.indicator image $imgred
ttk::style element create Green.Corner.TButton.indicator image $imggreen

Now create the layouts for each of the two button styles. The original ttk::button layout can be retrieved using:

set originalstyle [ttk::style layout TButton]
puts $originalstyle

We use this as a template and add in our indicator elements.

Note that the layout is different for different themes. The first example below is for the 'default' theme.

If you support multiple themes, you may want to retrieve ttk::button's layout for the theme and modify it using the string/regular expression facilities within Tcl.

# 'default' theme
ttk::style layout Red.Corner.TButton {
  Button.border -sticky nswe -border 1 -children {
    Button.focus -sticky nswe -children {
      Button.padding -sticky nswe -children {
        Button.label -sticky nswe 
        Red.Corner.TButton.indicator -side right -sticky ne}}}}


ttk::style layout Green.Corner.TButton {
  Button.border -sticky nswe -border 1 -children {
    Button.focus -sticky nswe -children {
      Button.padding -sticky nswe -children {
        Button.label -sticky nswe 
        Green.Corner.TButton.indicator -side right -sticky ne}}}}

Here is the modified layout for the 'vista' theme

# 'vista' theme
ttk::style layout Red.Corner.Button {
  Button.button -sticky nswe -children {
    Button.focus -sticky nswe -children {
      Button.padding -sticky nswe -children {
        Button.label -sticky nswe
        Red.Corner.TButton.indicator -side right -sticky ne}}}}

ttk::style layout Green.Corner.Button {
  Button.button -sticky nswe -children {
    Button.focus -sticky nswe -children {
      Button.padding -sticky nswe -children {
        Button.label -sticky nswe
        Green.Corner.TButton.indicator -side right -sticky ne}}}}

Now all the pieces are in place to create your buttons:

ttk::button .b -text hello -style Red.Corner.TButton

To change the indicator color, simply re-configure using the other style:

.b configure -style Green.Corner.TButton

References: https://www.tcl-lang.org/man/tcl/TkCmd/ttk_style.htm