Python PyGTK、线程和WebKit

Python PyGTK、线程和WebKit,python,multithreading,webkit,pygtk,Python,Multithreading,Webkit,Pygtk,在我的PyGTK应用程序中,单击按钮,我需要: 获取一些html(可能需要一些时间) 在新窗口中显示它 在获取html时,我想保持GUI的响应性,所以我决定在单独的线程中进行。我使用WebKit来呈现html 问题是,当WebView处于分离线程中时,我会在WebView中获得空页面 这项工作: import gtk import webkit webView = webkit.WebView() webView.load_html_string('<h1>Hello Mars&l

在我的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()
    
    导入gtk
    导入webkit
    webView=webkit.webView()
    webView.load_html_字符串('Hello Mars','file://'))
    window=gtk.window()
    添加(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()
    
    导入gtk
    导入webkit
    导入线程
    def show_html():
    webView=webkit.webView()
    webView.load_html_字符串('Hello Mars','file://'))
    window=gtk.window()
    添加(webView)
    window.show_all()
    thread=threading.thread(目标=show_html)
    setDaemon(True)
    thread.start()
    gtk.mainloop()
    

    是因为。有什么解决方法吗?

    我不知道webkit内部的工作原理,但也许你可以在多个进程中尝试它。

    根据我的经验,gtk有时不能像你预期的那样工作的一件事是在单独的线程中更新小部件

    为了解决这个问题,您可以在线程中处理数据,并在数据处理完成后,使用调度主线程中小部件的更新

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

    导入gtk,油嘴滑舌
    导入webkit
    导入线程
    导入时间
    #使用线程
    gtk.gdk.threads_init()
    类应用程序(对象):
    定义初始化(自):
    window=gtk.window()
    webView=webkit.webView()
    添加(webView)
    window.show_all()
    self.window=window
    self.webView=webView
    def运行(自):
    gtk.main()
    def show_html(self):
    #获取您的html字符串
    时间。睡眠(3)
    html_str='Hello Mars'
    #更新主线程中的小部件
    glib.idle\u add(self.webView.load\u html\u字符串,
    html_str,“文件://”)
    app=app()
    thread=threading.thread(target=app.show\u html)
    thread.start()
    app.run()
    gtk.main()
    
    您有一些代码可以共享吗?@jcollado添加了代码示例,请检查更新的问题。只需一些样式注释。分别使用
    thread.daemon=True
    gtk.main
    而不是
    thread.setDaemon(True)
    gtk.mainloop
    。thread.daemon=True和thread.setDaemon(True)之间有什么区别?
    setDaemon
    方法是设置
    daemon
    属性的旧方法。现在,与其使用setter方法,不如直接设置属性作为首选(更具python风格)方法。谢谢,这就成功了。有一件事需要注意,我试图将window.show_all()移动到show_html()方法,但由于分段错误而失败,很奇怪,不是吗?我使用了self.windowofc。你的意思是直接在
    show\uhtml
    方法中吗?如果需要,您可以定义另一个方法来执行此操作,然后使用
    webView.load\u html\u string
    并使用
    glib.idle\u add
    对其进行调度。为什么我不能在load\u html\u string之后直接在show\u html()中对其进行调度?pygtk明确指出它不是真正的线程安全,对于来自其他线程的所有操作,您必须使用idle\u add with threads\u enter/leave包装器
    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()