PyGTK,Threads和WebKit

时间:2011-12-25 17:18:25

标签: python multithreading webkit pygtk

在我的PyGTK应用程序中,点击按钮我需要:

  1. 获取一些HTML(可能需要一些时间)
  2. 在新窗口中显示
  3. 在获取html时,我想保持GUI响应,所以我决定在单独的线程中执行它。我使用WebKit来渲染html。

    问题是当它在分离的线程中时,我在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。有没有解决方法呢?

2 个答案:

答案 0 :(得分:3)

根据我的经验,有时用gtk不能正常工作的一件事就是在不同的线程中更新小部件。

要解决此问题,您可以使用线程中的数据,并在处理完数据后使用glib.idle_add来安排主线程中窗口小部件的更新。

以下代码是适合我的示例的更新版本(time.sleep用于模拟在真实场景中获取html的延迟):

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

答案 1 :(得分:0)

我对webkit内部工作一无所知,但也许你可以尝试使用多个进程。