How to set tkinter scale slider's color? How to set tkinter scale slider's color? tkinter tkinter

How to set tkinter scale slider's color?


To achieve what you want, we have to use a ttk style, so we need to use a ttk.Scale, however, it does not accept all the options of the tk.Scale you are using. Therefore, I suggest you to use the TickScale from the ttkwidgets module (See documentation here). This way you can combine the tk.Scale options with the ttk styling.

The idea is to:

  1. create images of the desired color for the slider, e.g. withtk.PhotoImage:

    img_slider = tk.PhotoImage(width=30, height=15)img_slider.put("{<pixel_color> ... <pixel_color>} {<second line>} ...")

    I used a basic rectangle, but you can also load a more elaborated image if you wish.

  2. create the colored slider theme element:

    style.element_create('custom.Horizontal.Scale.slider', 'image', img_slider,                     ('active', img_slider_active))

    I also used a different image img_slider_active, to highlight the slider when the cursor is on it.

  3. Use the new element in a custom style

    style.layout('custom.Horizontal.TScale',             [('Horizontal.Scale.trough',               {'sticky': 'nswe',                'children': [('custom.Horizontal.Scale.slider',                              {'side': 'left', 'sticky': ''})]})])
  4. Apply the custom style to your TickScale widget. Since the TickScale is based on a ttk.Scale, you need to use the style to set the background, foreground and troughcolor options, see full code below.
import tkinter as tkfrom tkinter import ttkfrom ttkwidgets import TickScaledef set_img_color(img, color):    """Change color of PhotoImage img."""    pixel_line = "{" + " ".join(color for i in range(img.width())) + "}"    pixels = " ".join(pixel_line for i in range(img.height()))    img.put(pixels)root = tk.Tk()# create images used for the themeslider_width = 30slider_height = 15# normal sliderimg_slider = tk.PhotoImage('img_slider', width=slider_width, height=slider_height, master=root)set_img_color(img_slider, "red")# active sliderimg_slider_active = tk.PhotoImage('img_slider_active', width=slider_width, height=slider_height, master=root)set_img_color(img_slider_active, '#1065BF')style = ttk.Style(root)style.theme_use('clam')# create scale elementstyle.element_create('custom.Horizontal.Scale.slider', 'image', img_slider,                     ('active', img_slider_active))# create custom layoutstyle.layout('custom.Horizontal.TScale',             [('Horizontal.Scale.trough',               {'sticky': 'nswe',                'children': [('custom.Horizontal.Scale.slider',                              {'side': 'left', 'sticky': ''})]})])style.configure('custom.Horizontal.TScale', background='black', foreground='grey',                troughcolor='#73B5FA')scale = TickScale(root, from_=0, to=100, tickinterval=100, orient="horizontal",                  style='custom.Horizontal.TScale')scale.pack(fill='x')root.mainloop()


slider.configure(foreground=color)

draws a rectangle around the slider, which distinguishes it from the trough. Setting the foreground color the same as the background color creates a difficult to find slider, as you stated.

Another option is to use a different theme (https://tkdocs.com/tutorial/styles.html). The snippet below allows you to see how your slider would look with different themes:

import tkinter as tkfrom tkinter import ttkclass App(tk.Tk):    def __init__(self):        super().__init__()        # root window        self.title('Theme Demo')        self.geometry('400x300')        self.style = ttk.Style(self)        # label        label = ttk.Label(self, text='Name:')        label.grid(column=0, row=0, padx=10, pady=10,  sticky='w')        # scale        slider = ttk.Scale(self, from_=1, to=10)        slider.grid(column=1, row=0, padx=10, pady=10,  sticky='w')        # button        btn = ttk.Button(self, text='Show')        btn.grid(column=2, row=0, padx=10, pady=10,  sticky='w')        # radio button        self.selected_theme = tk.StringVar()        theme_frame = ttk.LabelFrame(self, text='Themes')        theme_frame.grid(padx=10, pady=10, ipadx=20, ipady=20, sticky='w')        for theme_name in self.style.theme_names():            rb = ttk.Radiobutton(                theme_frame,                text=theme_name,                value=theme_name,                variable=self.selected_theme,                command=self.change_theme)            rb.pack(expand=True, fill='both')    def change_theme(self):        self.style.theme_use(self.selected_theme.get())if __name__ == "__main__":    app = App()    app.mainloop()