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.
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()
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')
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=...)