Search code examples
pythontkinterstylesttk

How to customize ttk.Checkbutton colors?


I am looking for a way to change the background color (and the active color) of the tickbox of the ttk.Checkbutton enter image description here

Optimally, the background color of the box should match the background's color?

What is the command to modify this in the style.configure() method?


Solution

  • It is possible to change the colors of the tickbox using the options indicatorbackground and indicatorforeground.

    style.configure("TCheckbutton", indicatorbackground="black", indicatorforeground="white",
                    background="black", foreground="white")
    

    To change the active colors, you need to use style.map() instead of style.configure().

    style.map("TCheckbutton", background=[("active", "darkgrey")])
    

    Note that with some themes (e.g. OSX and Windows default themes), the above commands do not produce any effect because the tickbox is created with an image. If this is the case, you can change the theme to use, for instance, "alt" or "clam", with style.theme_use("clam").

    If you want to keep using a theme that does not allow to change the tickbox color, you can use your own tickbox images instead:

    # create custom tickbox element
    img_unticked_box = tk.PhotoImage(file="/path/to/unticked_box_image")
    img_ticked_box = tk.PhotoImage(file="/path/to/ticked_box_image")
    style.element_create("tickbox", "image", img_unticked_box, ("selected", img_ticked_box))
    # replace the checkbutton indicator with the custom tickbox in the Checkbutton's layout
    style.layout(
        "TCheckbutton", 
        [('Checkbutton.padding',
          {'sticky': 'nswe',
           'children': [('Checkbutton.tickbox', {'side': 'left', 'sticky':     ''}),
        ('Checkbutton.focus',
             {'side': 'left',
              'sticky': 'w',
          'children': [('Checkbutton.label', {'sticky': 'nswe'})]})]})]
    )
    

    I obtained the layout of the Checkbutton with style.layout("TCheckbutton") and then replaced 'Checkbutton.indicator' by 'Checkbutton.tickbox'.