如何使用 tkinter 在两个不同的进度条中显示文本?
How to display text in two different Progressbars with tkinter?
我有一个 window 有两个不同的 Progressbar
。我想在它们上面添加不同的文本信息(即第一个是“88/1524”,第二个是“88/10000”)。
关于这个问题,我找到了一个 Progressbar
的解决方案:
但是它使用样式修改解决方法在进度条上添加文本,据我了解,样式属性 text.Horizontal.TProgressbar
为所有进度条共享。这意味着我不能在每个进度条上使用不同的文本。当我需要更新文本时,我不知道如何针对一个特定的进度条。
还有其他方法吗,还是我遗漏了什么?
我可以将标签实例化为 text.Horizontal.TProgressbar1
和 text.Horizontal.TProgressbar2
之类的东西吗?
这是我当前没有标签的设置:
我被困在什么地方:
我的部分代码:
style = tkinter.ttk.Style(root)
style.layout('text.Horizontal.TProgressbar',
[('Horizontal.Progressbar.trough',
{'children': [('Horizontal.Progressbar.pbar',
{'side': 'left', 'sticky': 'ns'})],
'sticky': 'nswe'}),
('Horizontal.Progressbar.label', {'sticky': ''})])
style.configure('text.Horizontal.TProgressbar', text='0/0')
ProgressBarOfDirectory = tkinter.ttk.Progressbar(ProgressbarFrame,
style='text.Horizontal.TProgressbar',
orient="horizontal",
length=WidthOfElements,
mode="determinate",
maximum=NbStepOfProgressBar,
variable=PourcentageOfDirectoryAnalysisDone)
ProgressBarOfDirectory.pack(side="top")
ProgressBarOfAll = tkinter.ttk.Progressbar(ProgressbarFrame,
style='text.Horizontal.TProgressbar',
orient="horizontal",
length=WidthOfElements,
mode="determinate",
maximum=NbStepOfProgressBar,
variable=PourcentageOfAllAnalysisDone)
进度条本身没有显示文字的功能。
您可以做的是使用标签小部件。您所要做的就是在您想要实现文本的地方放置一个标签小部件。
现在您可以配置标签的文本值,并且可以随着 Python Tkinter 进度条的变化而改变它。
在这里你可以找到一个例子:
from tkinter import *
from tkinter.ttk import Progressbar
import time
def step():
for i in range(5):
ws.update_idletasks()
pb['value'] += 20
time.sleep(1)
txt['text']=pb['value'],'%'
ws = Tk()
ws.title('PythonGuides')
ws.geometry('200x150')
ws.config(bg='#345')
pb = Progressbar(
ws,
orient = HORIZONTAL,
length = 100,
mode = 'determinate'
)
pb.place(x=40, y=20)
txt = Label(
ws,
text = '0%',
bg = '#345',
fg = '#fff'
)
txt.place(x=150 ,y=20 )
Button(
ws,
text='Start',
command=step
).place(x=40, y=50)
ws.mainloop()
小部件样式不会共享,除非它为多个小部件指定了相同的样式(或者由于未指定其他内容而将相同的默认样式分配给多个小部件)。
要利用这一点,这里是我的 另一个问题的代码的更新版本。为了保证每个 Progressbar
实例的独立性,它从内置的 ttk.Progressbar
派生出一个新的 class ,它为每个创建的实例创建一个单独的样式对象。
下面是代码以及最后的可运行演示。
import tkinter as tk
import tkinter.ttk as ttk
class MyProgressBar(ttk.Progressbar):
_inst_count = 0 # Number of class instances created.
def __init__(self, *args, **kwargs):
classname = type(self).__name__
assert 'style' not in kwargs, \
f'{classname} initializer does not support providing a ttk "style".'
type(self)._inst_count += 1 # Increment class attribute.
# Create a style with a different name for each instance.
self.style = ttk.Style(root)
self.stylename = f'text.Horizontal.TProgressbar{self._inst_count}'
self.style.layout(self.stylename,
[('Horizontal.Progressbar.trough',
{'children': [('Horizontal.Progressbar.pbar',
{'side': 'left', 'sticky': 'ns'})],
'sticky': 'nswe'}),
('Horizontal.Progressbar.label', {'sticky': ''})])
maximum = kwargs['maximum']
self.style.configure(self.stylename, text=f'0/{maximum}')
kwargs.update(style=self.stylename)
super().__init__(*args, **kwargs)
if __name__ == '__main__':
DELAY1 = 100
DELAY2 = 25
MAX1 = 1524
MAX2 = 10000
def progress_bar_func(delay, progress_bar):
# Start periodic progress-bar update process.
maximum = progress_bar.cget('maximum')
style = progress_bar.style # Progressbar must have a style attribute.
root.after(delay, update_progress_bar, delay, style, progress_bar, 1, maximum)
def update_progress_bar(delay, style, progress_bar, num, maximum):
if num <= maximum:
progress_bar.config(value=num)
style.configure(progress_bar.stylename, text=f'{num}/{maximum}')
num += 1
root.after(delay, update_progress_bar, delay, style, progress_bar, num, maximum)
root = tk.Tk()
root.geometry("300x300")
progress_bar1 = MyProgressBar(root, length=200, maximum=MAX1, value=0)
progress_bar1.pack()
progress_bar2 = MyProgressBar(root, length=200, maximum=MAX2, value=0)
progress_bar2.pack()
def start_progress_bars():
progress_bar_func(DELAY1, progress_bar1)
progress_bar_func(DELAY2, progress_bar2)
progress_button = tk.Button(root, text="Start", command=start_progress_bars)
progress_button.pack()
root.mainloop()
这是它的几个屏幕截图运行:
我有一个 window 有两个不同的 Progressbar
。我想在它们上面添加不同的文本信息(即第一个是“88/1524”,第二个是“88/10000”)。
关于这个问题,我找到了一个 Progressbar
的解决方案:
但是它使用样式修改解决方法在进度条上添加文本,据我了解,样式属性 text.Horizontal.TProgressbar
为所有进度条共享。这意味着我不能在每个进度条上使用不同的文本。当我需要更新文本时,我不知道如何针对一个特定的进度条。
还有其他方法吗,还是我遗漏了什么?
我可以将标签实例化为 text.Horizontal.TProgressbar1
和 text.Horizontal.TProgressbar2
之类的东西吗?
这是我当前没有标签的设置:
我被困在什么地方:
我的部分代码:
style = tkinter.ttk.Style(root)
style.layout('text.Horizontal.TProgressbar',
[('Horizontal.Progressbar.trough',
{'children': [('Horizontal.Progressbar.pbar',
{'side': 'left', 'sticky': 'ns'})],
'sticky': 'nswe'}),
('Horizontal.Progressbar.label', {'sticky': ''})])
style.configure('text.Horizontal.TProgressbar', text='0/0')
ProgressBarOfDirectory = tkinter.ttk.Progressbar(ProgressbarFrame,
style='text.Horizontal.TProgressbar',
orient="horizontal",
length=WidthOfElements,
mode="determinate",
maximum=NbStepOfProgressBar,
variable=PourcentageOfDirectoryAnalysisDone)
ProgressBarOfDirectory.pack(side="top")
ProgressBarOfAll = tkinter.ttk.Progressbar(ProgressbarFrame,
style='text.Horizontal.TProgressbar',
orient="horizontal",
length=WidthOfElements,
mode="determinate",
maximum=NbStepOfProgressBar,
variable=PourcentageOfAllAnalysisDone)
进度条本身没有显示文字的功能。
您可以做的是使用标签小部件。您所要做的就是在您想要实现文本的地方放置一个标签小部件。
现在您可以配置标签的文本值,并且可以随着 Python Tkinter 进度条的变化而改变它。
在这里你可以找到一个例子:
from tkinter import *
from tkinter.ttk import Progressbar
import time
def step():
for i in range(5):
ws.update_idletasks()
pb['value'] += 20
time.sleep(1)
txt['text']=pb['value'],'%'
ws = Tk()
ws.title('PythonGuides')
ws.geometry('200x150')
ws.config(bg='#345')
pb = Progressbar(
ws,
orient = HORIZONTAL,
length = 100,
mode = 'determinate'
)
pb.place(x=40, y=20)
txt = Label(
ws,
text = '0%',
bg = '#345',
fg = '#fff'
)
txt.place(x=150 ,y=20 )
Button(
ws,
text='Start',
command=step
).place(x=40, y=50)
ws.mainloop()
小部件样式不会共享,除非它为多个小部件指定了相同的样式(或者由于未指定其他内容而将相同的默认样式分配给多个小部件)。
要利用这一点,这里是我的 Progressbar
实例的独立性,它从内置的 ttk.Progressbar
派生出一个新的 class ,它为每个创建的实例创建一个单独的样式对象。
下面是代码以及最后的可运行演示。
import tkinter as tk
import tkinter.ttk as ttk
class MyProgressBar(ttk.Progressbar):
_inst_count = 0 # Number of class instances created.
def __init__(self, *args, **kwargs):
classname = type(self).__name__
assert 'style' not in kwargs, \
f'{classname} initializer does not support providing a ttk "style".'
type(self)._inst_count += 1 # Increment class attribute.
# Create a style with a different name for each instance.
self.style = ttk.Style(root)
self.stylename = f'text.Horizontal.TProgressbar{self._inst_count}'
self.style.layout(self.stylename,
[('Horizontal.Progressbar.trough',
{'children': [('Horizontal.Progressbar.pbar',
{'side': 'left', 'sticky': 'ns'})],
'sticky': 'nswe'}),
('Horizontal.Progressbar.label', {'sticky': ''})])
maximum = kwargs['maximum']
self.style.configure(self.stylename, text=f'0/{maximum}')
kwargs.update(style=self.stylename)
super().__init__(*args, **kwargs)
if __name__ == '__main__':
DELAY1 = 100
DELAY2 = 25
MAX1 = 1524
MAX2 = 10000
def progress_bar_func(delay, progress_bar):
# Start periodic progress-bar update process.
maximum = progress_bar.cget('maximum')
style = progress_bar.style # Progressbar must have a style attribute.
root.after(delay, update_progress_bar, delay, style, progress_bar, 1, maximum)
def update_progress_bar(delay, style, progress_bar, num, maximum):
if num <= maximum:
progress_bar.config(value=num)
style.configure(progress_bar.stylename, text=f'{num}/{maximum}')
num += 1
root.after(delay, update_progress_bar, delay, style, progress_bar, num, maximum)
root = tk.Tk()
root.geometry("300x300")
progress_bar1 = MyProgressBar(root, length=200, maximum=MAX1, value=0)
progress_bar1.pack()
progress_bar2 = MyProgressBar(root, length=200, maximum=MAX2, value=0)
progress_bar2.pack()
def start_progress_bars():
progress_bar_func(DELAY1, progress_bar1)
progress_bar_func(DELAY2, progress_bar2)
progress_button = tk.Button(root, text="Start", command=start_progress_bars)
progress_button.pack()
root.mainloop()
这是它的几个屏幕截图运行: