我正在wxPython中写一个聊天室客户端,其中笔记本页面上每个聊天室有3个wx.HtmlWindows
:一个用于消息,一个用于房间标题,一个用于房间主题(两个相似的事情)
程序运行正常,当图像在消息代码中时加载图像等。但是当它突然需要一次加载一堆图像,或者需要更长时间加载的动画图像或组合时(图像)它通常只是50x50 - 100x100)它可能是一个问题,因为有时它会锁定,然后程序将不会响应,因为它花了太长时间。提出的问题是,我如何阻止锁定发生?我不知道如何绑定wx.HtmlWindow
的图像加载以使图像在工作线程中动态加载,而不是程序必须等待图像加载才能继续。
如果您需要我正在撰写的示例代码,请告诉我。
编辑:我仍然无法找到答案。因为这个原因,我在这个项目上几乎没有。我的应用程序需要能够在没有锁定的情况下动态加载消息/图像,我根本不知道如何强制将任何图像加载到不同的线程中,以便在加载器线程加载时显示图像和消息的帧完成后,图像和更新空帧。这一切都需要在HtmlWindow中发生。我希望它在加载图像时表现得像真正的网络浏览器(你会看到框架和图像慢慢显示)答案 0 :(得分:0)
长时间运行的进程将阻止应用程序的主循环,从而导致其“锁定”。您需要在单独的线程中进行下载,然后在完成后更新UI。以下是使用可能对您有帮助的线程(以及其他方法)的一些链接:
http://wiki.wxpython.org/LongRunningTasks
http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/
答案 1 :(得分:0)
除了迈克的答案(他说的内容适用)之外,您还可以通过覆盖HTMLWindow中的OnOpeningURL方法并指定wx.html.HTML_URL_IMAGE
的类型来挂接到正在加载的图像。
请参阅:these wx docs获取解释。
答案 2 :(得分:0)
您可能想在最新的wxPython开发版本中试用新功能吗?
您首先需要确保已下载并安装了最新版本。 您可以在“开发版本”下找到它:http://www.wxpython.org/download.php
这是一个与最新的wxPython(v2.9)开发版本一起使用的简单示例:
import wx
import wx.html2
class MyBrowser(wx.Dialog):
def __init__(self, *args, **kwds):
wx.Dialog.__init__(self, *args, **kwds)
sizer = wx.BoxSizer(wx.VERTICAL)
self.browser = wx.html2.WebView.New(self)
sizer.Add(self.browser, 1, wx.EXPAND, 10)
self.SetSizer(sizer)
self.SetSize((700, 700))
if __name__ == '__main__':
app = wx.App()
dialog = MyBrowser(None, -1)
dialog.browser.LoadURL("http://www.google.com")
dialog.Show()
app.MainLoop()
我希望这能解决你的问题,让我知道。
答案 3 :(得分:0)
Steven Sproat走在正确的轨道上(感谢我把它放在上面 - 没有你的建议就不能这样做) - 这是完整解决方案的相关部分:
import wx.html as html
import urllib2 as urllib2
import os
import tempfile
import threading
from Queue import Queue
class HTTPThread(threading.Thread):
def __init__(self, urlQueue, responseQueue):
threading.Thread.__init__(self)
self.urlQueue = urlQueue
self.responseQueue = responseQueue
def run(self):
# add error handling
url = self.urlQueue.get()
request = urllib2.Request(url)
response = urllib2.urlopen(request)
page = response.read()
self.responseQueue.put(page)
在你的派生类html.HtmlWindow:
def OnOpeningURL(self, type, url):
if type == html.HTML_URL_IMAGE:
# If it is a tempfile already, just tell it to open it.
# Since it will be called again
# immediately after first failure only need to keep the last
# temp file within the object, and the former is closed!
if self.f is not None and self.f.name in url:
return html.HTML_OPEN
# if its not a tempfile, download asynchronously and redirect
urlq = Queue()
resq = Queue()
t = HTTPThread(urlq, resq)
t.start()
urlq.put_nowait(url)
while True:
if resq.empty():
# your task while waiting
time.sleep(0.1)
else:
img = resq.get()
break
self.f = tempfile.NamedTemporaryFile()
self.f.write(img)
self.f.seek(0)
return 'file://' + self.f.name
else:
return html.HTML_OPEN
对于我的应用程序,这非常有用,但是如果你真的想要像“常规网络浏览器”一样加载图像,那么你需要的不仅仅是wx.html.HtmlWindow。但是,这是非阻塞的,并且会正确加载图像。