Python PyGTK、线程和WebKit
在我的PyGTK应用程序中,单击按钮,我需要: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
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()