Skip to main content
 首页 » 编程设计

python之PyGTK、线程和 WebKit

2024年08月30日47Leo_wl

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

  1. 获取一些 html(可能需要一些时间)
  2. 在新窗口显示

在获取 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()