【问题标题】:Serving resource to QWebView of PyQT5为 PyQT5 的 QWebView 提供资源
【发布时间】:2014-04-30 08:41:36
【问题描述】:

如何将桌面应用程序的资源(html、css、js、字体等文件)提供给 QWebView(在 PyQT5 中)?

我想要的是:

  1. 如果可能,由 PyQT5 的 Webkit 引擎处理请求的资源 使用像 custom://app/jquery.js 这样的自定义方案并返回文件。
  2. 如果可能,处理标准 http 动词(GET、POST、...) 自定义方案。

如果这 2 个都不可能(至少以纯 Python 方式不可能):

  • 如何拦截来自嵌入式 Webkit 的请求和 根据 url 中的模式提供资源(html、css、js)(比如说 一些正则表达式(?<controller>[^/])/(?<action>[^/]))?

【问题讨论】:

    标签: python python-3.x pyqt qtwebkit pyqt5


    【解决方案1】:

    您需要创建自己的 QNetworkAccessManager 子类,它为所需协议返回自定义 QNetworkReply,然后将其设置为您 QWebView 页面的网络访问管理器。

    This article 展示了如何做到这一点的一个很好的例子 - 应用于 PyQt5,这就是它的外观:

    from PyQt5.QtCore import QUrl, QTimer, QIODevice
    from PyQt5.QtWidgets import QApplication
    from PyQt5.QtNetwork import (QNetworkAccessManager,
                                 QNetworkReply,
                                 QNetworkRequest)
    from PyQt5.QtWebKitWidgets import QWebView
    
    import sys
    
    class ExampleNetworkAccessManager(QNetworkAccessManager):
    
        def __init__(self, parent=None):
            super().__init__(parent=parent)
    
        def createRequest(self, operation, request, device):
            if request.url().scheme() == 'example':
                return ExampleReply(self, operation, request, device)
            return super().createRequest(operation, request, device)
    
    
    class ExampleReply(QNetworkReply):
    
        def __init__(self, parent, operation, request, device):
            super().__init__(parent=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):
            if self.operation() == QNetworkAccessManager.PostOperation:
                # handle operations ...
                pass
            # some dummy content for this example
            self.content = b'''<html>
                <h1>hello world!</h1>
                <p>...</p>
                </html>'''
            self.open(QIODevice.ReadOnly | QIODevice.Unbuffered)
            self.setHeader(QNetworkRequest.ContentLengthHeader, len(self.content))
            self.setHeader(QNetworkRequest.ContentTypeHeader, "text/html")
            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().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()
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        wv = QWebView()
        enam = ExampleNetworkAccessManager()
        wv.page().setNetworkAccessManager(enam)
        wv.show()
        wv.setUrl(QUrl("example://test.html"))
        app.exec()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多