0

I am using python with gtk. I want to download a file, and while this is happening i draw an animated gif on the window. But everytime the download starts, the gif is freezing. I thought the gobject call should fix this, but seems not like.

The call is:

in the gui class

  ...
  gobject.timeout_add(3000, self.load)
  gtk.main()

and the load function:

 def load(self):
     ul = urllib2.open('http://xxxx/')
     data = ul.read()
     while gtk.events_pending():
          gtk.main_iteration()
     return True

with every call of load the gui stacks. Any way to do that better?

original code:

self.opener = urllib2.build_opener() 
self.opener.addheaders.append(('Cookie', self.cookie)) 
self.state = self.opener.open('http://'+gd_adress+'/state.cst?Lang=en')
self.state_data = self.state.read()
HappyHacking
  • 878
  • 1
  • 12
  • 28

1 Answers1

4

You need to use an asynchronous call that integrates with the GObject main loop.

Probably the easiest is to use GIO:

import gio

f = gio.File(uri='http://xxxx/')
def on_ready(gdaemonfile, result):
    data, length, tag = f.load_contents_finish(result)
f.load_contents_async(on_ready)

Jono Bacon has a great writeup: http://www.jonobacon.org/2010/03/15/download-files-async-with-gio-and-python/

Unfortunately GIO doesn't support setting HTTP cookies as far as I can tell. In that case the best option is probably to use threads and use GLib.idle_add to return data to the main loop, as in Webkit threads with PyGObject on Gtk3:

import threading
import glib
glib.threads_init()

def load_data():
    opener = urllib2.build_opener() 
    opener.addheaders.append(('Cookie', cookie)) 
    state = opener.open('http://'+gd_adress+'/state.cst?Lang=en')
    state_data = state.read()
    glib.idle_add(on_read_data, state_data)
thread = threading.Thread(target=load_data)
thread.start()

The idea is that this encapsulates the blocking call in a thread that returns data to the main thread when it is ready, so the rest of your code can ignore the fact that threads are being used.

Community
  • 1
  • 1
ecatmur
  • 152,476
  • 27
  • 293
  • 366
  • Yeah thats quite what i need. But i need to add a cookie information to the http header.. how to do this here? Here is the code i have really: – HappyHacking Aug 22 '12 at 11:50
  • if i try it like this i get an error: GLib.threads_init() NameError: name 'GLib' is not defined – HappyHacking Aug 22 '12 at 12:52
  • @user1508490 it might be `glib` lower case. Depending on the version you might have to use `gtk.threads_init` instead of `glib.threads_init` and/or `gobject.idle_add` instead of `glib.idle_add`. – ecatmur Aug 22 '12 at 12:59
  • yeah thanks a lot!! i got it 1 second befor you wrote me :) Now its working very awesome :) – HappyHacking Aug 22 '12 at 13:00