2010-09-28 62 views
1

我正在wxPython中寫一個聊天室客戶端,其中有3個wx.HtmlWindows用於筆記本頁面上的每個聊天室:一個用於消息,一個用於房間標題,另一個用於主題的房間(兩個類似的東西)wxPython - 加載圖片時HtmlWindow凍結

該程序工作正常,當圖像在消息的代碼中時加載圖像等。但是,當它突然需要加載一堆圖像或一個動畫圖像需要更長的時間加載,或組合(圖像通常只有50x50 - 100x100),這可能是一個問題,因爲有時它會鎖定,然後程序不會響應,因爲它需要太長時間。提出的問題是,我將如何阻止發生鎖定?我不知道如何去綁定wx.HtmlWindow的圖像加載,以便在工作線程中動態加載圖像,而不是等待圖像加載才能繼續。

如果您需要我寫的內容的示例代碼,請告訴我。

編輯:我還是老樣子有麻煩找出一個答案這個..我已經得到了字面上沒有地方在這個項目上因爲這個原因。我的應用程序需要能夠動態加載消息/圖像,而不鎖定它,並且我根本不知道如何強制將任何圖像加載到不同的線程中,以便在加載程序線程加載時顯示圖像和消息的幀圖像並在完成時更新空白幀。這一切都需要在HtmlWindow中發生。我希望它像一個真正的web瀏覽器,當談到加載圖像(你看到的框架和圖像慢慢出現)

回答

0

長時間運行的進程將阻止應用程序的主循環,這會導致它「鎖定」。您需要在單獨的線程中進行下載,然後在完成後更新UI。下面是關於使用線程(或其它方法)幾個鏈接,可以幫助你:

http://wiki.wxpython.org/LongRunningTasks

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

+0

這並不能真正幫助他解決問題,因爲他不確定在哪裏綁定正在加載的圖像。 – 2010-09-29 15:07:24

+0

我已經知道如何使用線程我只是不知道如何讓窗口在不同的線程中進行圖像加載。謝謝 – Blazer 2010-09-29 23:37:50

+0

我在想你可以用線程下載圖像,然後使用PubSub或PostEvent來告訴你的應用程序顯示它。 – 2010-09-30 14:03:59

0

除了小李的答案(他說的話適用),你可以連接到一個圖像通過覆蓋HTMLWindow中的OnOpeningURL方法並指定wx.html.HTML_URL_IMAGE的類型來加載。

請參閱:these wx docs一個解釋。

+0

謝謝!你碰巧知道如何讓wxHtmlWindow在加載頁面時添加一個空白幀來代替圖像,然後在完成加載後更新頁面?通過這種方式,消息不會與實際接收時間混淆起來(例如,在消息帶圖像之後實際收到的圖像可能會首先出現,例如搞亂訂單) – Blazer 2010-09-29 23:42:12

+0

嗯,我'米不確定,對不起。我沒有使用過wx.HtmlWindow – 2010-09-30 12:22:02

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

我希望這能解決你的問題, 讓我知道。

0

史蒂芬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更多。但是,這是非阻塞的並且會正確加載圖像。