1

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

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

如果您需要我正在编写的示例代码,请告诉我。

编辑:我仍然无法找到答案。因为这个,我在这个项目上几乎没有任何地方。我的应用程序需要能够在不锁定的情况下动态加载消息/图像,我根本不知道如何强制将任何图像加载到不同的线程中,以便在加载器线程加载时显示图像和消息的帧图像并在完成后更新空帧。这一切都需要在 HtmlWindow 中发生。我希望它在加载图像时表现得像一个真正的网络浏览器(你会看到框架和图像慢慢出现)

4

4 回答 4

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()

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

于 2012-06-04T21:31:04.987 回答
0

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

http://wiki.wxpython.org/LongRunningTasks

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

于 2010-09-29T13:41:49.343 回答
0

除了 Mike 的回答(他所说的适用)之外,您还可以通过覆盖 HTMLWindow 中的 OnOpeningURL 方法并指定wx.html.HTML_URL_IMAGE.

请参阅:这些 wx 文档以获取解释。

于 2010-09-29T16:06:43.207 回答
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。但是,这是非阻塞的,并且会正确加载图像。

于 2013-03-14T17:29:44.697 回答