Why Can't I View Updates To A Label While Making An Http Request In Python
Solution 1:
Below is a working example of a simple downloader for illustration purposes only. You need to use multi-threading if you want your GUI to be responsive and not freeze while you do some long running or blocking operation. I put this example together based on this stack overflow question and this excellent article Using threads in PyGTK. The default url an Ubuntu iso will take a while to download and should provide a good demonstration . You can enter any url you want when prompted it will download and save the file in the current directory.
from threading import Thread
import time
import gtk, gobject, urllib
URL = 'http://releases.ubuntu.com//precise/ubuntu-12.04.1-desktop-i386.iso'defdownload(url):
filename = url.split('/')[-1]
out = open(filename, 'wb')
gobject.idle_add(label.set_text, "connecting...")
f = urllib.urlopen(url)
buffer = f.read(1024)
counter = 0while buffer:
counter += len(buffer)
out.write(buffer)
msg = "downloaded {0:,} bytes".format(counter)
gobject.idle_add(label.set_text, msg)
buffer = f.read(1024)
out.close()
gobject.idle_add(label.set_text, "download complete")
defclicked(button):
url = entry.get_text()
Thread(target=download, args=(url,)).start()
gtk.gdk.threads_init()
win = gtk.Window()
win.set_default_size(400, 100)
entry = gtk.Entry()
entry.set_text(URL)
label = gtk.Label("Press the button")
button = gtk.Button(label="Download")
button.connect('clicked', clicked)
box = gtk.VBox()
box.pack_start(entry)
box.pack_start(label)
box.pack_start(button)
win.add(box)
win.show_all()
gtk.main()
Solution 2:
Gtk doesn't update anything until the main loop runs. That means it first does all its changes and only updates after they're all done. This is because it intends all callbacks to be atomic (finish in a negligible time). A callback should never use a blocking call, because it means the interface will freeze.
There are two possible solutions here. The best is to register a new callback when a response is ready, and return to the main loop. However, this may not be easy. A dirty workaround is to force the main loop to handle pending events before making the blocking call. It will then update the label. You can do this with
while gtk.events_pending ():
gtk.main_iteration (False)
But as I wrote, not calling any blocking functions from the callback is much cleaner.
Post a Comment for "Why Can't I View Updates To A Label While Making An Http Request In Python"