0

我正在使用带有 gtk 的 python。我想下载一个文件,当这发生时,我在窗口上绘制了一个动画 gif。但是每次下载开始时,gif都会冻结。我认为 gobject 调用应该解决这个问题,但似乎不像。

电话是:

在 gui 类中

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

和加载功能:

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

每次调用加载 gui 堆栈。有什么办法可以做得更好吗?

原始代码:

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()
4

1 回答 1

4

您需要使用与 GObject 主循环集成的异步调用。

可能最简单的是使用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 有一篇很棒的文章:http: //www.jonobacon.org/2010/03/15/download-files-async-with-gio-and-python/

不幸的是,据我所知,GIO 不支持设置 HTTP cookie。在这种情况下,最好的选择可能是使用线程并用于GLib.idle_add将数据返回到主循环,就像在Gtk3 上带有 PyGObject 的 Webkit 线程中一样

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()

这个想法是将阻塞调用封装在一个线程中,该线程在准备好时将数据返回给主线程,因此您的其余代码可以忽略线程正在使用的事实。

于 2012-08-22T11:31:18.713 回答