wxPython-加载图像时HtmlWindow冻结

wxPython-加载图像时HtmlWindow冻结,python,wxpython,wxhtmlwindow,Python,Wxpython,Wxhtmlwindow,我正在用wxPython编写一个聊天室客户端,其中笔记本页面上的每个聊天室都有3个wx.HtmlWindows:一个用于消息,一个用于聊天室的标题,另一个用于聊天室的主题(两个类似的东西) 该程序工作正常,当图像出现在消息代码中时加载图像,等等。但是当它突然不得不一次加载一组图像,或者加载需要更长时间的动画图像,或者一个组合(图像通常只有50x50-100x100)时这可能是一个问题,因为有时它会锁定,然后程序不会响应,因为它花费的时间太长。提出的问题是,我如何阻止锁定的发生?我不知道如何绑定w

我正在用wxPython编写一个聊天室客户端,其中笔记本页面上的每个聊天室都有3个
wx.HtmlWindows
:一个用于消息,一个用于聊天室的标题,另一个用于聊天室的主题(两个类似的东西)

该程序工作正常,当图像出现在消息代码中时加载图像,等等。但是当它突然不得不一次加载一组图像,或者加载需要更长时间的动画图像,或者一个组合(图像通常只有50x50-100x100)时这可能是一个问题,因为有时它会锁定,然后程序不会响应,因为它花费的时间太长。提出的问题是,我如何阻止锁定的发生?我不知道如何绑定
wx.HtmlWindow
的图像加载,让图像在工作线程中动态加载,而不是让程序等待图像继续加载

如果你需要一个什么样的代码我写让我知道


编辑:我仍然很难找到答案。。因为这个,我在这个项目上毫无进展。我的应用程序需要能够在不锁定的情况下动态加载消息/图像,我只是不知道如何将任何图像加载到不同的线程中,以便显示图像和消息的帧,而加载程序线程加载图像并在完成后更新空帧。这一切都需要在HtmlWindow中发生。我希望在加载图像时,它能像一个真正的web浏览器一样工作(您可以看到帧和图像慢慢出现)

长时间运行的进程会阻塞应用程序的主循环,从而导致应用程序“锁定”。您将希望在单独的线程中进行下载,然后在下载完成后更新UI。以下是一些关于使用线程(和其他方法)的链接,可能会对您有所帮助:


除了Mike的答案(他所说的适用),您还可以通过覆盖HTMLWindow中的OnOpeningURL方法并指定
wx.html.html\u URL\u image
的类型来连接正在加载的图像


请参阅:以获取解释。

您可能希望在最新的wxPython开发版本中试用新功能

您首先需要确保已下载并安装了最新版本。 您可以在这里的“开发版本”下找到它:

这是一个适用于最新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()

我希望这能解决您的问题,让我知道。

史蒂文·斯普劳特走上了正确的道路(很荣幸让我这么做——没有您的建议是不可能做到的)-以下是完整解决方案的相关部分:

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

对于我的应用程序来说,这非常有效,但是如果您真的希望像普通的web浏览器一样加载图像,那么您需要的不仅仅是wx.html.HtmlWindow。但是,这是非阻塞的,可以正确加载图像。

这对他的问题没有帮助,因为他不确定要将加载的图像绑定到哪里。我已经知道如何使用线程,只是不确定如何让窗口在不同的线程中加载图像。谢谢,我想你可以用这个线程下载图片,然后用PubSub或PostEvent告诉你的应用程序显示它。谢谢!您是否知道如何让wxHtmlWindow在加载页面时添加一个空白框来代替图像,然后在加载完成后更新页面?这样一来,信息就不会从实际接收时就被混淆(没有图像的信息实际上是在有图像的信息出现之后才被接收到的,例如,这会打乱顺序)嗯,我不确定,抱歉。我没有使用wx.HtmlWindow