在我的PyGTK应用程序中,点击按钮我需要:
在获取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。有没有解决方法呢?
答案 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内部工作一无所知,但也许你可以尝试使用多个进程。