PySide downloading file with progress bar

In this tutorial, we will download a file by HTTP and display the downloading progress by progress bar. The final screenshot is like this:



Downloading File

To display the downloading progress, we need know file size and currently downloaded bytes size.

So how to get the size of file need download? If you're familiar with HTTP, it will go easy. When downloading a file, first client will send a HTTP request to server for the file URL, then the server will send back a HTTP response to client. If requested URL is valid, the response body will be the file content.In the response header, there's a field called "Content-Length", which is used to indicate size of the response body. Since response body here is the file content, so this "Content-Length" is what we're looking for.

First we need use urllib2.urlopen() to open an url, this method returns a response object. Chain method info().get_headers() of response object can fetch the response header.So we can get file size like this:

And next, we need know how many bytes we have downloaded.
the read(n) method of response object will receive n bytes of data from server. Actually read() can be called with no parameter, then it will receive all data sent by server. But calling read() method like that will let urllib2 module to handle the whole transferring progress. we cannot know how many bytes have been downloaded until downloading is finished.

To get currently downloaded bytes size, we need download fixed size of bytes everytime and update the downloaded bytes size after that block of bytes are downloaded. Then continue downloading until all data is received. You got the idea? so lets implement it.


Display Progress Bar

Now we need QProgressBar to display our downloading progress. set_value() method of QProgressBar is used to set value of progress bar. The default value range is 0-100. and you can modify them by using setMinimum() and setMaximum() of QProgressBar.
Following code will create a window and put a progress bar in it. a setProgress() method is provided to set the progress bar value, so the downloading thread can set progress bar value by calling this method.



We will need put downloading part in a separate thread, otherwise it will block UI.

So here's the complete source code