下载栏不能正常工作,Python?

时间:2017-06-27 08:03:19

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

所以我在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()

1 个答案:

答案 0 :(得分: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:花了很多时间来弄清楚那是什么。