2

I'm trying to create a custom progress bar widget that has some text (Label) above it, and I have to change the background (Progressbar) bar color in some situations, but I'm struggling to understand Tkinter's documentation as for the Style and Themes...

I'm trying to combine j_4321 and clan + martineau solutions for this.

I've created a Style layout like this:

progressbar_style = Style(self)
progressbar_style.layout(
    'pb1.text.Horizontal.TProgressbar', 
    [
        (
            'Horizontal.Progressbar.trough',  # main proressbar definition
            {'children': 
                [
                    ('Horizontal.Progressbar.pbar',  # main progressbar
                            {
                                'side': 'left', 
                                'sticky': 'ns',
                            }
                    )
                ],
                'sticky': 'nswe'
            }
        ), 
        (
            # transparent label text over progressbar
            'Horizontal.Progressbar.label', {'sticky': 'nswe'}  
        )
    ]
)

And using this allows me to change the overlayed Label text color

# foreground argument determines the text color
progressbar_style.configure('pb1.text.Horizontal.TProgressbar', text='lorem ipsum', anchor='center', foreground='red', background='yellow')

Result progress bar

But unlike seen in the clan + martineau's solution, the background argument doesn't seem to change the progress bar color. And even troughcolor hasn't worked for me for this. How can I specify the widget part I want to configure (as in the previous configure method)?

2 Answers2

2

Customized: You have to use the style definition and than assign to your widget:

import tkinter as tk
from tkinter import ttk
import time

def increment(*args):
    for i in range(100):
        p1["value"] = i+1
        root.update()
        time.sleep(0.1)
        pb_style.configure('text.Horizontal.TProgressbar', 
                    text=f"{p1['value']} %") 
root = tk.Tk()
root.geometry('300x50')

# define the style
pb_style = ttk.Style()
print(pb_style.theme_names())
# ('winnative', 'clam', 'alt', 'default', 'classic', 'vista', 'xpnative')
pb_style.theme_use("default")
pb_style.layout('text.Horizontal.TProgressbar', 
             [('Horizontal.Progressbar.trough',
               {'children': [('Horizontal.Progressbar.pbar',
                              {'side': 'left', 'sticky': 'ns'})],
                'sticky': 'nswe'}), 
              ('Horizontal.Progressbar.label', {'sticky': 'nswe'})])
pb_style.configure('text.Horizontal.TProgressbar', text='0 %', anchor='center', foreground='red', background='yellow' )
#pb_style.configure("yellow.Vertical.TProgressbar", troughcolor="gray", background="yellow")

p1 = ttk.Progressbar(root, length=200, cursor='spider',
                     mode="determinate",
                     orient=tk.HORIZONTAL,
                     style='text.Horizontal.TProgressbar'
                     )
p1.grid(row=1,column=1)


btn = ttk.Button(root,text="Start",command=increment)
btn.grid(row=1,column=0)
root.mainloop()

Output: enter image description here

Hermann12
  • 1,709
  • 2
  • 5
  • 14
  • But I'm using it, my progress bar even got the overlayed label widget working, and with that configure call I was able to customize it – Giordano Souza Dec 23 '22 at 22:26
0

With a small change to the style layout I was able to modify the text, text color and the color of the bar itself, but I couldn't keep my system default theme on the progress bar, which made me change all other progress bars I had in my application.

First of all here's how they look like under different themes:

vista (default on my system - Windows 10): vista progressbar

clam: clam progressbar

xpnative: xpnative progressbar

Without calling the configure method to edit the style, the progress bar keeps the system default, and after it seems to change to xpnative, unless changed with another theme command, but I couldn't get it back to the default vista one (winnative, alt, default, classic all changed to xpnative after configuring).

The clam and xpnative themes are the only ones that currently work for me, where I can acess and modify the text itself and progress bar and text colors.

Here's how the style layout I'm using looks like:

# this is inside a Frame class
progressbar_style = Style(self)  

# creating a colored progress bar (i'm currently using the clam theme)
progressbar_style.element_create('color.pbar', 'from', 'clam')

# new style layout
progressbar_style.layout(
    'pb1', 
    [
        (   
            # main proressbar definition
            'Horizontal.Progressbar.trough',  
            {
                'sticky': 'nswe',
                'children': 
                [
                    (
                        # colored progressbar
                        'Horizontal.Progressbar.color.pbar',  
                        {
                            'side': 'left', 
                            'sticky': 'ns'
                        }
                    )
                ],
            }
        ), 
        (
            # transparent label text over progressbar
            'Horizontal.Progressbar.label', {'sticky': 'nswe'}  
        )
    ]
)

Here's the progress bar widget, taking the new created style as an argument

audio_level_indicator = Progressbar(
    master = self  # frame where the progressbar is used
    variable = self.audio_level,  # DoubleVar control variable
    mode = 'determinate',
    maximum = 20,
    style = 'pb1'  # new style just modified
)

And here's the configure command to modify its attributes

progressbar_style.configure(
    'pb1',  # style argument
    text = 'Sample text',  # progress bar text - for the overlayed label
    background='blue',  # progress bar color
    foreground='red'  # text color
)

output bar: output bar

But it's unfortunate that I couldn't use the vista theme for this, I had to change the rest of my application to match the new theme.