在我的 PyGTK 应用程序中,单击按钮时我需要:
- 获取一些 html(可能需要一些时间)
- 在新窗口显示
在获取 html 时,我想保持 GUI 响应,所以我决定在单独的线程中进行。我使用 WebKit 来呈现 html。
问题是当 WebView 在单独的线程中时,我在 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 .有什么解决方法吗?
请您参考如下方法:
根据我的经验,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()
