【问题标题】:Download bar not working properly, Python?下载栏无法正常工作,Python?
【发布时间】:2017-06-27 08:03:18
【问题描述】:

所以我用 Python 制作了一个应用程序,通过单击界面上的按钮从 Internet 下载文件。用户还必须在下载前命名文件。正在下载的文件是 Microsoft 病毒定义(因为它是一个大文件)。我有一个进度条来显示下载进度,但我遇到了以下两个问题之一:

这是我尝试的一种方法,当我单击按钮时,文件下载,但进度条立即显示已完成。代码如下:

def download():
    link = "http://go.microsoft.com/fwlink/?LinkID=87341"
    filename = "C:/My Python Apps/" + txtName.get() +".exe"

    r = requests.get(link, stream=True)
    f = open(filename, "wb")
    fileSize = int(r.headers["Content-Length"])
    chunk = 1
    chunkSize = 1024
    bars = int(fileSize/chunkSize)
    print(dict(num_bars=bars))
    with open(filename, "wb") as fp:
        for chunk in tqdm(r.iter_content(chunk_size=chunkSize), total=bars, unit="KB",
                          desc=filename, leave=True):
            fp.write(chunk)
            progress["value"] = fileSize
    return

我尝试的另一种方法效果更好,因为当下载开始时,它不会立即射到栏的末尾。但问题是在下载还没有达到 1% 之前,即使文件仍在下载,进度条已经完成。下面是这个函数的代码:

    link = "http://go.microsoft.com/fwlink/?LinkID=87341"
    filename = "C:/My Python Apps/" + txtName.get() +".exe"

    r = requests.get(link, stream=True)

    totalSize = int(r.headers.get("content-length", 0))

    with open(filename, "wb") as f:
        i = 0
        for data in tqdm(r.iter_content(32*1024), total=totalSize, unit="B", unit_scale=True):
            f.write(data)
            progress["value"] = i
            i += 1
        return

如何让进度条准确、正确地指示下载进度?

如果有帮助,这是我的应用程序的完整代码:

from threading import Thread
from tkinter import *
from tkinter import Tk, ttk


def downloadThread():
    Thread(target=download).start()

def download():

    # Place either of the functions in the question here...


root = Tk()

w = 400
h = 135
ws = root.winfo_screenwidth()
wh = root.winfo_screenheight()
x = (ws / 2) - (w / 2)
y = (wh / 2) - (h / 2)
root.geometry("%dx%d+%d+%d" % (w, h, x, y))
root.title("MyApp beta")

lblName = Label(root, text="File name: ")
lblName.place(x=5, y=5)
txtName = Entry(root, width=25)
txtName.place(x=5, y=25)
value = IntVar()
progress = ttk.Progressbar(root, length=155)
progress.place(x=5, y=50)
btnDownload = Button(root, text="Download Definition", width=21,
                     command=lambda: downloadThread())
btnDownload.place(x=5, y=100)
lblLoad = Label(root, text="Downloading, please wait...")
lblLoad.place_forget()

root.mainloop()

【问题讨论】:

    标签: python-3.x tkinter progress-bar download


    【解决方案1】:

    在第一个实现中,您立即将进度条的值设置为完整文件大小。你想要的是使它成为文件大小的一小部分(已经下载的那个)。

    这行得通:

    def download():
        link = "http://go.microsoft.com/fwlink/?LinkID=87341"
        filename = "C:/My Python Apps/" + txtName.get() +".exe"
    
        r = requests.get(link, stream=True)
        f = open(filename, "wb")
        fileSize = int(r.headers["Content-Length"])
        chunk = 1
        downloaded = 0 # keep track of size downloaded so far
        chunkSize = 1024
        bars = int(fileSize/chunkSize)
        print(dict(num_bars=bars))
        with open(filename, "wb") as fp:
            for chunk in tqdm(r.iter_content(chunk_size=chunkSize), total=bars, unit="KB",
                              desc=filename, leave=True):
                fp.write(chunk)
                downloaded += chunkSize # increment the downloaded
                progress["value"] = (downloaded*100/fileSize)#*100 #Default max value of tkinter progress is 100
        return
    

    顺便说一句,你没有导入tqdm:花了很多时间才弄清楚那是什么。

    【讨论】:

    • 你传说它有效! :D。为缺少 tqdm 导入道歉,我在复制代码时不小心没有突出显示它。但是非常感谢。
    猜你喜欢
    • 2019-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-16
    • 1970-01-01
    • 2016-08-16
    • 1970-01-01
    相关资源
    最近更新 更多