【问题标题】:wxPython WebView: how to reload on error?wxPython WebView:如何重新加载错误?
【发布时间】:2019-04-16 09:35:51
【问题描述】:

我正在使用wx.html2.WebView 在对话框中加载网站,工作正常很好。

问题:如果出于任何原因无法访问网站,输出将为Could not connect: Connection refused

期望的行为:尝试在每次失败 x 秒后重新加载 URL

import wx 
import wx.html2 
import time

URL = "http://mydomain.tld"

class MyBrowser(wx.Frame): 
  def __init__(self, *args, **kwds): 
    wx.Frame.__init__(self, *args, **kwds) 
    self.browser = wx.html2.WebView.New(self) 
    self.browser.Bind(wx.html2.EVT_WEBVIEW_ERROR, self.on_webview_error)

  def on_webview_error(self, evt):
    # Printing works
    print("Error: can't load page, try again in 3 seconds.")
    # Sleeping works
    time.sleep(3)
    # Reloading doesn't work
    self.browser.LoadURL(URL) # OR self.browser.Reload()
    # Weird: Error is rendered now


if __name__ == '__main__': 
  app = wx.App() 
  dialog = MyBrowser(None, -1) 
  dialog.browser.LoadURL(URL) 
  dialog.Show() 
  app.MainLoop() 

问题出现在on_webview_error(self, evt)。我的猜测是我没有正确使用该功能,特别是因为错误消息是在重新加载后呈现的。

有什么想法吗?
提前致谢!

【问题讨论】:

    标签: python python-3.x webview event-handling wxpython


    【解决方案1】:

    那里发生了一些奇怪的事情!
    我可以强制它工作的唯一方法是每次重新定义WebView。我可能每次都对Destroy 过于热情。
    这可行,但不一定完全符合您的要求。

    import wx
    import wx.html2
    import time
    
    URL = "http://mydomain.tld"
    
    class MyBrowser(wx.Frame):
        def __init__(self, *args, **kwds):
            wx.Frame.__init__(self, *args, **kwds)
            self.url = URL
            self.browser = wx.html2.WebView.New(self, -1, size=(900,600))
            self.browser.Bind(wx.html2.EVT_WEBVIEW_ERROR, self.on_webview_error)
            self.browser.Bind(wx.html2.EVT_WEBVIEW_LOADED, self.on_webview_load)
            self.retries = 0
            self.max_retries = 10
    
        def on_webview_error(self, evt):
            self.URL = evt.GetURL()
            print(self.URL)
            self.retries += 1
            if self.retries > self.max_retries: # Give up
                self.Destroy()
            print("Error {} of {} attempts to load {}, trying again in 3 seconds.".format(self.retries,self.max_retries,self.URL))
            if self.retries > 5: # Try alternate
                self.URL = "http://wxPython.org"
                print("Swapping to alternate Url "+self.URL)
            self.browser.Destroy()
    
            time.sleep(3)
    
            self.browser = wx.html2.WebView.New(self, -1, size=(900,600))
            self.browser.Bind(wx.html2.EVT_WEBVIEW_ERROR, self.on_webview_error)
            self.browser.Bind(wx.html2.EVT_WEBVIEW_LOADED, self.on_webview_load)
            self.browser.LoadURL(self.URL)
    
        def on_webview_load(self, evt):
            print(self.URL, "Load complete")
    
    if __name__ == '__main__':
      app = wx.App()
      dialog = MyBrowser(None, -1)
      dialog.browser.LoadURL(URL)
      dialog.Show()
      app.MainLoop()
    

    【讨论】:

    • 我同意,这很奇怪,但至少它有效。非常感谢你! :-)
    【解决方案2】:

    在 wxPython 中,您总是有一个主线程,它负责绘制和更新 GUI。在您的 MWE 中,time.sleep(3) 行允许您等待 3 秒钟,然后再尝试重新加载页面。但是,这具有在能够更新 GUI 并显示错误消息之前将程序的主线程发送到睡眠状态的副作用。如果您将 time.sleep(3) 行移至不同的线程,则 GUI 可能会毫无问题地更新。这是一个解决方案:

    import wx 
    import wx.html2 
    import time
    import _thread
    from pubsub import pub
    
    URL = "https://mydomain.tld"
    
    class MyBrowser(wx.Frame): 
        def __init__(self, *args, **kwds): 
            wx.Frame.__init__(self, *args, **kwds) 
            self.browser = wx.html2.WebView.New(self) 
            self.browser.Bind(wx.html2.EVT_WEBVIEW_ERROR, self.on_webview_error)
            self.counter = 0
            pub.subscribe(self.loadwww, 'Try Again')
            pub.subscribe(self.loadalt, 'Give UP')
    
        def loadwww(self):
            self.browser.LoadURL("https://mydomain.tld")
    
        def loadalt(self):
            self.browser.LoadURL("https://www.google.com")
    
        def on_webview_error(self, evt):
            self.counter += 1
            _thread.start_new_thread(self.wait, (3,))   
    
        def wait(self, sec):
            if self.counter <= 5:
                print(self.counter)
                print("Error: can't load page, try again in 3 seconds.")
                time.sleep(sec)
                wx.CallAfter(pub.sendMessage, 'Try Again')
            else:
                wx.CallAfter(pub.sendMessage, 'Give UP')    
    
    if __name__ == '__main__': 
        app = wx.App() 
        dialog = MyBrowser(None, -1) 
        dialog.browser.LoadURL(URL) 
        dialog.Show() 
        app.MainLoop()
    

    【讨论】:

      猜你喜欢
      • 2014-07-21
      • 2019-12-04
      • 1970-01-01
      • 1970-01-01
      • 2023-04-06
      • 2015-06-17
      • 2014-05-10
      • 2015-06-28
      • 2022-11-11
      相关资源
      最近更新 更多