Progressbar with Percentage Label?

label, python, tkinter, transparency

Solution

This is possible using a `ttk.Style`. The idea is to modify the layout of the `Horizontal.TProgressbar` style (do the same with `Vertical.TProgressbar` for a vertical progressbar) to add a label inside the bar:

Usual `Horizontal.TProgressbar` layout:

[('Horizontal.Progressbar.trough',
  {'children': [('Horizontal.Progressbar.pbar',
     {'side': 'left', 'sticky': 'ns'})],
   'sticky': 'nswe'})]

With an additional label:

[('Horizontal.Progressbar.trough',
  {'children': [('Horizontal.Progressbar.pbar',
     {'side': 'left', 'sticky': 'ns'})],
   'sticky': 'nswe'}),
 ('Horizontal.Progressbar.label', {'sticky': 'nswe'})]

Then, the text of the label can be changed with `style.configure`.

Here is the code:

import tkinter as tk
from tkinter import ttk

root = tk.Tk()

style = ttk.Style(root)
# add label in the layout
style.layout('text.Horizontal.TProgressbar', 
             [('Horizontal.Progressbar.trough',
               {'children': [('Horizontal.Progressbar.pbar',
                              {'side': 'left', 'sticky': 'ns'})],
                'sticky': 'nswe'}), 
              ('Horizontal.Progressbar.label', {'sticky': 'nswe'})])
# set initial text
style.configure('text.Horizontal.TProgressbar', text='0 %', anchor='center')
# create progressbar
variable = tk.DoubleVar(root)
pbar = ttk.Progressbar(root, style='text.Horizontal.TProgressbar', variable=variable)
pbar.pack()

def increment():
    pbar.step()  # increment progressbar 
    style.configure('text.Horizontal.TProgressbar', 
                    text='{:g} %'.format(variable.get()))  # update label
    root.after(200, increment)
    
increment()

root.mainloop()

Styling

The font, color and position of the label can be changed using `style.configure`. For instance,

style.configure('text.Horizontal.TProgressbar', foreground="red", 
                font='Arial 20', anchor='w')

gives

Multiple progressbars

The text is set through the style therefore to have multiple progressbars with different labels, one needs to use a different style for each. However, there is no need to set the layout for each style: create the layout `'text.Horizontal.TProgressbar'` like in the above code and then use substyles `'pb1.text.Horizontal.TProgressbar'`, `'pb2.text.Horizontal.TProgressbar'`, ... for each progressbar. Then the text of a single progressbar can be changed with

style.configure('pb1.text.Horizontal.TProgressbar', text=...)

Problem

How can I put a label in the middle of a progressbar that shows the percentage? The problem is that python doesn't support transparency for label backgrounds, so I don't know how I can solve that.

Original source

Related problems