如何在ttk中创建下载进度条?

33 投票
5 回答
88797 浏览
提问于 2025-04-17 01:30

我想在从网上下载文件的时候显示一个进度条,使用的是 urllib.urlretrieve 这个方法。

我该怎么用 ttk.Progressbar 来完成这个任务呢?

这是我到目前为止做的:

from tkinter import ttk
from tkinter import *

root = Tk()

pb = ttk.Progressbar(root, orient="horizontal", length=200, mode="determinate")
pb.pack()
pb.start()

root.mainloop()

但是它一直在循环。

5 个回答

5

如果你只是想要一个进度条来显示程序正在忙或者在工作,那只需要把模式从“确定的”改成“不确定的”就可以了。

pb = ttk.Progressbar(root,orient ="horizontal",length = 200, mode ="indeterminate")
10

我把代码简化了,方便你理解。

import sys
import ttk
from Tkinter import *

mGui = Tk()

mGui.geometry('450x450')
mGui.title('Hanix Downloader')

mpb = ttk.Progressbar(mGui,orient ="horizontal",length = 200, mode ="determinate")
mpb.pack()
mpb["maximum"] = 100
mpb["value"] = 50

mGui.mainloop()

50换成你下载进度的百分比。

40

在确定模式下,你不需要调用 start。相反,只需设置小部件的 value 值,或者调用 step 方法就可以了。

如果你提前知道要下载多少字节(我想你是知道的,因为你在使用确定模式),最简单的方法就是把 maxvalue 选项设置为你要读取的字节数。然后,每次读取一部分数据时,你就把 value 设置为已读取的总字节数。进度条会自动计算出百分比。

这里有个模拟示例,可以让你大致了解一下:

import tkinter as tk
from tkinter import ttk


class SampleApp(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.button = ttk.Button(text="start", command=self.start)
        self.button.pack()
        self.progress = ttk.Progressbar(self, orient="horizontal",
                                        length=200, mode="determinate")
        self.progress.pack()

        self.bytes = 0
        self.maxbytes = 0

    def start(self):
        self.progress["value"] = 0
        self.maxbytes = 50000
        self.progress["maximum"] = 50000
        self.read_bytes()

    def read_bytes(self):
        '''simulate reading 500 bytes; update progress bar'''
        self.bytes += 500
        self.progress["value"] = self.bytes
        if self.bytes < self.maxbytes:
            # read more bytes after 100 ms
            self.after(100, self.read_bytes)

app = SampleApp()
app.mainloop()

为了让这个工作正常,你需要确保不会阻塞图形界面的线程。这意味着你要么像示例那样分块读取,要么在一个单独的线程中进行读取。如果你使用线程,你将无法直接调用进度条的方法,因为 tkinter 是单线程的。

你可能会发现 tkdocs.com 上的 进度条示例 对你有帮助。

撰写回答