class CustomQWebPage(QWebPage): """ QWebPage subclass with a signal for load finished with a parameter for page errors. """ loadFinishedWithError = pyqtSignal(bool, QWebPage.ErrorPageExtensionOption) _dummy_error = QWebPage.ErrorPageExtensionOption() def __init__(self, *args, **kwargs): super(CustomQWebPage, self).__init__(*args, **kwargs) self.webview = None self._current_error = None self.loadFinished.connect(self._on_load_finished) self.loadStarted.connect(self.reset_curent_error) def setNetworkAccessManager(self, nam): super(CustomQWebPage, self).setNetworkAccessManager(nam) self.networkAccessManager().finished.connect(self._on_network_reply) def reset_curent_error(self): self._current_error = None def _on_network_reply(self, reply): if self._current_error: return if reply.error() == QNetworkReply.NoError: self._current_error = MyErrorPageExtensionOption() self._current_error.domain = QWebPage.Http self._current_error.error = reply.attribute( QNetworkRequest.HttpStatusCodeAttribute) self._current_error.url = reply.url() self._current_error.errorString = reply.attribute( QNetworkRequest.HttpReasonPhraseAttribute) self._current_error.headers = dict( map(partial(map, str), reply.rawHeaderPairs())) def _on_load_finished(self, ok): # TODO: check if Qt accepts None instead of _dummy_error. error = self._current_error or self._dummy_error if error.domain == QWebPage.Http: ok = True self.loadFinishedWithError.emit(ok, error) self.reset_curent_error() def extension(self, extension, option=None, output=None): if extension == QWebPage.ErrorPageExtension: if self._current_error is None: self._current_error = option return False def supportsExtension(self, extension): if extension == QWebPage.ErrorPageExtension: return True return super(CustomQWebPage, self).supportsExtension(extension)
class CustomQWebPage(QWebPage): """ QWebPage subclass with a signal for load finished with a parameter for page errors. """ loadFinishedWithError = pyqtSignal(bool, QWebPage.ErrorPageExtensionOption) _dummy_error = QWebPage.ErrorPageExtensionOption() _dummy_error.domain = QWebPage.Http def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.webview = None self._current_error = None self.loadFinished.connect(self._on_load_finished) def setNetworkAccessManager(self, nam): super().setNetworkAccessManager(nam) self.networkAccessManager().finished.connect(self._on_network_reply) def _has_error(self): return (self._current_error and not isinstance( self._current_error, MyErrorPageExtensionOption)) def _on_network_reply(self, reply): if self._has_error(): return if not self._current_error and reply.error() == QNetworkReply.NoError: if reply.attribute(QNetworkRequest.RedirectionTargetAttribute): return self._current_error = MyErrorPageExtensionOption() self._current_error.domain = QWebPage.Http self._current_error.error = reply.attribute( QNetworkRequest.HttpStatusCodeAttribute) self._current_error.url = reply.url() self._current_error.errorString = reply.attribute( QNetworkRequest.HttpReasonPhraseAttribute) self._current_error.headers = { bytes(h): bytes(v) for h, v in reply.rawHeaderPairs() } # TODO: network error. def _on_load_finished(self, ok): error = self._current_error or self._dummy_error self._current_error = None self.loadFinishedWithError.emit(ok, error) def extension(self, extension, option=None, output=None): if extension == QWebPage.ErrorPageExtension: if not self._has_error(): self._current_error = option return False def supportsExtension(self, extension): if extension == QWebPage.ErrorPageExtension: return True return super().supportsExtension(extension)