2011-12-25 4 views
2

、ボタンをクリックして私がする必要がありhtmlを取得するには、GUIの応答性を維持したいので、別のスレッドで行うことにしました。私はHTMLをレンダリングするためにWebKitを使用します。PyGTKを、スレッドとWebKitの私のPyGTKのアプリで

問題は、分離されたスレッドでWebViewで空のページが表示されることです。

これは動作します:

import gtk 
import webkit 

webView = webkit.WebView() 
webView.load_html_string('<h1>Hello Mars</h1>', 'file:///') 
window = gtk.Window() 
window.add(webView) 
window.show_all() 
gtk.mainloop() 

これは動作しませんが、空のウィンドウを生成します。

import gtk 
import webkit 
import threading 

def show_html(): 
    webView = webkit.WebView() 
    webView.load_html_string('<h1>Hello Mars</h1>', 'file:///') 
    window = gtk.Window() 
    window.add(webView) 
    window.show_all() 

thread = threading.Thread(target=show_html) 
thread.setDaemon(True) 
thread.start() 
gtk.mainloop() 

はそれが理由webkit is not thread-safeです。このための回避策はありますか?

+0

あなたはあなたができるいくつかのコードを持っていますか:

次のコードは、(実際のシナリオでHTMLを得ることに遅延をシミュレートするために使用されtime.sleepを)私の作品あなたの例の更新版ですシェア? – jcollado

+0

@jcolladoコード例を追加しました。更新された質問を確認してください。 – umpirsky

+0

ちょっとしたスタイルノート。 'thread.setDaemon(True)'と 'gtk.mainloop'の代わりに' thread.daemon = True'と 'gtk.main'をそれぞれ使用してください。 – jcollado

答えて

3

私の経験によれば、あなたがgtkで期待するように動作しないことの1つは、別々のスレッドでのウィジェットの更新です。

この問題を回避するには、スレッド内のデータを操作し、glib.idle_addを使用して、データが処理された後でメインスレッドのウィジェットの更新をスケジュールします。

import gtk, glib 
import webkit 
import threading 
import time 

# Use threads          
gtk.gdk.threads_init() 

class App(object): 
    def __init__(self): 
     window = gtk.Window() 
     webView = webkit.WebView() 
     window.add(webView) 
     window.show_all() 

     self.window = window 
     self.webView = webView 

    def run(self): 
     gtk.main() 

    def show_html(self): 
     # Get your html string      
     time.sleep(3) 
     html_str = '<h1>Hello Mars</h1>' 

     # Update widget in main thread    
     glib.idle_add(self.webView.load_html_string, 
         html_str, 'file:///') 

app = App() 

thread = threading.Thread(target=app.show_html) 
thread.start() 

app.run() 
gtk.main() 
+0

ありがとう、それはトリックでした。私はwindow.show_all()メソッドをshow_html()メソッドに移動しようとしましたが、それはSegmentationフォールトで失敗しました。私はself.window ofcを使いました。 – umpirsky

+0

'show_html'メソッドで直接意味しますか?必要な場合は、それと 'webView.load_html_string'を実行する別のメソッドを定義し、' glib.idle_add'を使ってそれをスケジュールすることができます。 – jcollado

+0

load_html_stringの直後にshow_html()で直接スケジュールを設定できないのはなぜですか? – umpirsky

0

私はWebkitの内部動作について何も知らないが、多分複数のプロセスで試すことができます。

+0

更新された質問のコード例を確認してください。ありがとう。 – umpirsky