Progress bar only appears when the download ends

Asked

Viewed 91 times

0

Guys, here’s the thing, I was doing a progress bar for a download of a file on the web, but it doesn’t work. When I run the code, the Tkinter window is locked and only returns when the download is finished. Does anyone know what I’m missing? I am already 2 days in this problem. Follow the code part below:

def read_bytes(self):
with open(file_name, "wb") as f:
    response = requests.get(linkd, stream=True)
    total_length = response.headers.get('content-length')
    if total_length is None:
        f.write(response.content)
    else:
        dl = 0
        total_length = int(total_length)
        for data in response.iter_content(chunk_size=4096):
            dl += len(data)
            f.write(data)
            self.bytes = dl
            self.progress["value"] = self.bytes
            if self.bytes < self.maxbytes:
                self.after(100)
            elif self.bytes >= self.maxbytes:
                self.exit = ttk.Label(self, text="Terminado",
                                       background = 'black',
                                       foreground = 'white')
                                       self.exit.pack()

1 answer

2


The problem is not the progress bar that crashes the program, but the download code. The graphical interface of tkinter always wheel in main thread and no more code can run on it from the moment you run the mainloop or your interface may crash.

A good example of this is the function time.sleep that makes the program sleep and locks the interface:

def btn_function():
    time.sleep(2)

root = Tk()
Button(root, text = "Aguardar 2 segundos", command = btn_function).pack()
root.mainloop()

In the above example, the programmer who created the code thought he could make the program just wait with the time.sleep without locking the interface, but this does not occur because the function is called in the main thread.

"But my code doesn’t ask for the program to sleep, it just downloads a file."

Really, but there is a wait until the download is done, being precisely this wait that affects the interface and makes it hang for a while.

The solution to this is to create a Thread, so that the execution of your download does not affect the execution of the graphical interface.

Take this example:

from tkinter import *
from threading import Thread
import requests

def download():
    response = requests.get("<url>")
    with open('page.html','wb') as file:
        file.write(response.content)

def btn_function():
    print("Downloading...")
    Thread(target = download).start()

root = Tk()
Button(root, text = "Download", command = btn_function).pack()
root.mainloop()
  • 1

    Thanks bro! I adapted my code with this concept that you presented and apparently worked out great, great explanation. Solved issue :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.