wxPython WebView:如何在出错时重新加载?
wxPython WebView: how to reload on error?
我正在使用 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)
。我的猜测是我没有正确使用该功能,尤其是因为错误消息是在重新加载后呈现的。
有什么想法吗?
提前致谢!
那里发生了一些奇怪的事情!
我可以强制它工作的唯一方法是每次都重新定义 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()
在 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()
我正在使用 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)
。我的猜测是我没有正确使用该功能,尤其是因为错误消息是在重新加载后呈现的。
有什么想法吗?
提前致谢!
那里发生了一些奇怪的事情!
我可以强制它工作的唯一方法是每次都重新定义 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()
在 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()