PyGTK、线程和 WebKit

发布于 2024-12-22 17:37:20 字数 946 浏览 3 评论 0原文

在我的 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 不是线程安全的。有什么解决方法吗?

In my PyGTK app, on button click I need to:

  1. Fetch some html (can take some time)
  2. Show it in new window

While fetching html, I want to keep GUI responsive, so I decided to do it in separate thread. I use WebKit to render html.

The problem is I get empty page in WebView when it is in separated thread.

This works:

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

This does not work, produces empty window:

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

Is it because webkit is not thread-safe. Is there any workaround for this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

秋意浓 2024-12-29 17:37:20

根据我的经验,有时 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()

According to my experience, one of the things that sometimes doesn't work as you expect with gtk is the update of widgets in separate threads.

To workaround this problem, you can work with the data in threads, and use glib.idle_add to schedule the update of the widget in the main thread once the data has been processed.

The following code is an updated version of your example that works for me (the time.sleep is used to simulate the delay in getting the html in a real scenario):

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()
×眷恋的温暖 2024-12-29 17:37:20

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

I don't know anything about webkit inner workings, but maybe you can try it with multiple processes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文