代码之家  ›  专栏  ›  技术社区  ›  Blazer

wxpython-htmlwindow在加载图像时冻结

  •  1
  • Blazer  · 技术社区  · 14 年前

    我正在写一个wxpython的聊天室客户,里面有3个 wx.HtmlWindows 对于笔记本页面上的每个聊天室:一个用于留言,一个用于会议室标题,一个用于会议室主题(两个相似的东西)

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

    如果你需要我写的东西的样本代码,请告诉我。

    编辑:我还是很难找到答案。因为这个,我在这个项目上几乎没有任何进展。我的应用程序需要能够动态加载消息/图像,而不需要将其锁定,我只是不知道如何强制将任何图像加载到不同的线程中,以便显示图像和消息的帧,而加载程序线程则加载图像并更新空的拉面完成后。这一切都需要在HTMLWindow中发生。我希望它在加载图像时像一个真正的Web浏览器(您可以看到帧和图像慢慢出现)

    4 回复  |  直到 11 年前
        1
  •  0
  •   Mike Driscoll    14 年前

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

    http://wiki.wxpython.org/LongRunningTasks

    http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/

        2
  •  0
  •   Steven Sproat    14 年前

    除了Mike的回答(他所说的适用),您还可以通过从HTMLWindow重写OnOpeningURL方法并指定 wx.html.HTML_URL_IMAGE .

    见: these wx docs 为了解释。

        3
  •  0
  •   patchie    12 年前

    您可能希望在最新的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()
    

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

        4
  •  0
  •   bbbruce    11 年前

    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。但是,这是非阻塞的,将正确加载图像。