如何使用 tkinter 在两个不同的进度条中显示文本?

How to display text in two different Progressbars with tkinter?

我有一个 window 有两个不同的 Progressbar。我想在它们上面添加不同的文本信息(即第一个是“88/1524”,第二个是“88/10000”)。 关于这个问题,我找到了一个 Progressbar 的解决方案:

但是它使用样式修改解决方法在进度条上添加文本,据我了解,样式属性 text.Horizontal.TProgressbar 为所有进度条共享。这意味着我不能在每个进度条上使用不同的文本。当我需要更新文本时,我不知道如何针对一个特定的进度条。

还有其他方法吗,还是我遗漏了什么? 我可以将标签实例化为 text.Horizontal.TProgressbar1text.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()

这是它的几个屏幕截图运行: