public
Created

A little program to show how a gtk gui gets unresponsive when using gtk2reactor and downloading a file with twisted.web.client.HTTPDownloader.

  • Download Gist
gui_slowdown.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
 
"""
A little program to show how a gtk gui gets unresponsive when using
gtk2reactor and downloading a file with twisted.web.client.HTTPDownloader.
 
Enter the url (HTTP) of a large file into the textbox and press start.
The progress bar becomes visibly jerky, while I'd expect that it stays
smooth. Apparently twisted doesn't return control to GTK fast enough.
 
To set up a mini web server, you can use:
$ twistd -n web --path /path/to/large/file
 
"""
 
from urlparse import urlparse
import gtk, gobject
 
from twisted.internet import gtk2reactor
gtk2reactor.install()
 
from twisted.internet import reactor, defer
import twisted.web.client as twc
 
 
class MainWindow(gtk.Window):
def __init__(self):
gtk.Window.__init__(self)
self.set_default_size(300, 150)
 
vb = gtk.VBox(spacing=6)
self.add(vb)
 
self.enURL = gtk.Entry()
self.enURL.set_text("http://localhost:8080/video.avi")
vb.pack_start(self.enURL, False, True)
 
self.lblStatus = gtk.Label("Press Start")
vb.pack_start(self.lblStatus, False, True)
 
self.bbButtons = gtk.HButtonBox()
vb.pack_start(self.bbButtons, False, True)
self.btnStart = gtk.Button("Start")
self.btnStart.connect("clicked", self.btnStart_clicked)
self.bbButtons.pack_start(self.btnStart)
 
self.pbDemo = gtk.ProgressBar()
self.pbDemo.set_text("Testing smoothness")
vb.pack_start(self.pbDemo, False, True)
 
vb.pack_start(gtk.HBox(), True, False)
vb.pack_start(gtk.Statusbar(), False, True)
 
gobject.timeout_add(50, self.update_spinner, [0])
 
vb.show_all()
 
@defer.inlineCallbacks
def btnStart_clicked(self, widget):
url = self.enURL.get_text()
scheme, host, port, path = twc._parse(url)
filename = path.rpartition("/")[2]
outfile = filename
print url, "->", outfile
factory = twc.HTTPDownloader(url, outfile)
self.btnStart.set_sensitive(False)
self.enURL.set_sensitive(False)
self.lblStatus.set_text("Downloading...")
 
print host, port
self.connector = reactor.connectTCP(host, port, factory)
 
result = yield factory.deferred
print "finished"
print result
 
self.btnStart.set_sensitive(True)
self.enURL.set_sensitive(True)
self.lblStatus.set_text("Done!")
 
def update_spinner(self, status):
old = status[0]
new = old + 2
if new > 100:
new = 0
self.pbDemo.set_fraction(float(new)/100.)
status[0] = new
return True
 
 
def main():
win = MainWindow()
win.show_all()
reactor.run()
 
 
if __name__ == "__main__":
main()

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.