如何将内容写入QNetworkReprat(原:QWebview与生成的内容)



我正在使用QWebview来显示由同一程序生成的html。现在 html 可以引用其他资源,例如<FRAME src=...>在框架套装中。当浏览器开始下载该资源时,我必须拦截该请求并自己补充内容,因为不涉及网络服务器。我可以用来赶上请求的 url 并提供生成内容的钩子在哪里?

要创建浏览器微件:

self.browser = QWebView()
self.layout.addWidget(self.browser)

要加载框架集:

self.browser.setHtml(ret.text)

现在我希望找到的是一些信号,然后

self.browser.requestURI.connect(myhandler)

但我没有看到类似的东西。这里更好的方法是什么?


编辑:

主要问题似乎是使用setHtml。因此,似乎绕过了所有加载机制。使用load()QNetworkAccessManager结合使用,我得到了更好的结果(见下文)。现在响应对象已提供给我的内容管理器,但是,到目前为止,我未能向响应对象写入任何内容(或实例化一个新的对象)。可以通过访问模式参数打开它。然后只读错误消失,但仍然写入返回 -1。

我相应地改写了这个问题的标题。

from PyQt5.Qt import *  # @UnusedWildImport
class ContentManager(object):
def handleRequest(self, request, response):
#         response.writeData(bytearray("hello new year", "utf-8")) #THIS WORKS NOT
return response

class NAM(QNetworkAccessManager):
def __init__(self, contentManager):
super().__init__()
self.contentManager = contentManager
def createRequest(self, operation, request, device):
response = super().createRequest(operation, request, device)
return self.contentManager.handleRequest(request, response)
class Browser(QWidget):
def __init__(self):
super().__init__()
def open(self, url):
self.browser.load(QUrl(url))
def build(self, contentManager):
layout = QVBoxLayout(self)
view = QWebView()
page = view.page(); view.setPage(page)
page.setNetworkAccessManager(NAM(contentManager))
layout.addWidget(view)
self.browser = view        
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
w   = Browser()
w.build(ContentManager())
w.open("index.html")
w.show()
app.exec_() 

您需要实现自定义QNetworkReply,通常可以提供您想要"注入"到Webview(html,文本,图像)中的任何内容。

我不确定本地文件和帧,但是当您使用必须通过QNetworkAccessManager解决的"假域"时,它将起作用。

以下非常简单的示例使用 Python 3.6.3 和 PyQt 5.10.0:

from PyQt5.Qt import *  # @UnusedWildImport
import signal, os, sys
signal.signal(signal.SIGINT, signal.SIG_DFL)

class ContentHandler(object):
def __init__(self, url):
self.url = url
def __call__(self):
print ('ContentHandler >>', self.url)
path, basename = os.path.split(self.url)
if basename == 'index.html':
return b"hello new year", 'text/html'

class DownloadReply(QNetworkReply):
def __init__(self, parent, operation, request):
super(DownloadReply, self).__init__(parent)
self.setRequest(request)
self.setOperation(operation)
self.setUrl(request.url())
self.bytes_read = 0
self.content = b''
# give webkit time to connect to the finished and readyRead signals
QTimer.singleShot(200, self.load_content)
def load_content(self):
self.content, self.data = ContentHandler(str(self.url().toString()))()
self.offset = 0
self.open(QIODevice.ReadOnly | QIODevice.Unbuffered)
self.setHeader(QNetworkRequest.ContentTypeHeader, QVariant(self.data))
self.setHeader(QNetworkRequest.ContentLengthHeader, QVariant(len(self.content)))
self.readyRead.emit()
self.finished.emit()
def abort(self):
pass
def isSequential(self):
return True
def bytesAvailable(self):
ba = len(self.content) - self.bytes_read + super(DownloadReply, self).bytesAvailable()
return ba
def readData(self, size):
if self.bytes_read >= len(self.content):
return None
data = self.content[self.bytes_read:self.bytes_read + size]
self.bytes_read += len(data)
return data
def manager(self):
return self.parent()

class NetworkAccessManager(QNetworkAccessManager):
def __init__(self, parent=None):
super(NetworkAccessManager, self).__init__(parent=parent)
def createRequest(self, operation, request, device):
if str(request.url().host()).lower() == "myfakedom.ain":
print ('request:', request.url().host())
return DownloadReply(self, self.GetOperation, request)
return super(NetworkAccessManager, self).createRequest(operation, request, device)

if __name__ == '__main__':
app = QApplication(sys.argv)
webView = QWebView()
webView.settings().setAttribute(QWebSettings.PluginsEnabled, True)
webView.settings().setAttribute(QWebSettings.DeveloperExtrasEnabled, True)
webView.settings().setAttribute(QWebSettings.AutoLoadImages, True)
webView.settings().setAttribute(QWebSettings.JavascriptEnabled, True)
webInspector = QWebInspector()
nam = NetworkAccessManager()
webView.page().setNetworkAccessManager(nam)
webView.load(QUrl('http://myFakeDom.ain/index.html'))
webInspector.setPage(webView.page())
window = QMainWindow()
window.setCentralWidget(webView)
window.setFixedSize(1200, 840)
window.setWindowTitle('Test')
window.show()
sys.exit(app.exec_())

最新更新