0

私はgtkでpythonを使用しています。ファイルをダウンロードしたいのですが、これが起こっている間に、ウィンドウにアニメーション GIF を描画します。しかし、ダウンロードが開始されるたびに、gif がフリーズします。gobject 呼び出しでこれを修正する必要があると思いましたが、そうではないようです。

呼び出しは次のとおりです。

ギークラスで

  ...
  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

load を呼び出すたびに、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は私が知る限りHTTPCookieの設定をサポートしていません。その場合、 Gtk3でPyGObjectを使用するWebkitスレッドのように、スレッドを使用GLib.idle_addしてデータをメインループに返すために使用するのがおそらく最善のオプションです。

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 に答える