Python PyQt5子类化QNetworkAccessManager :: createRequest数据复制

时间:2015-12-21 22:07:32

标签: python pyqt webkit qnetworkaccessmanager qnetworkreply

在开发使用PyQt5的特定系统期间,我需要子类化QNetworkAccessManager以覆盖createRequest方法。我这样做是为了在WebView呈现它们之前保存HTTP资源并清理缓冲区(这是一个QIODevice)。

我正在使用peek(),因此缓冲区在进入webview时不会被清除。

但是,有些时候缓冲区一旦到达WebView就不会被清除,我注意到当WebKit / WebView不支持内容时会发生这种情况,但其他时候似乎也会发生。 由于我将数据附加到我自己的变量(基于事后缓冲区被清除的事实),这会导致数据重复。

例如:

<script>hello</script

如果数据未被清除,我将收到的消息可能是:

<script<script>hello</script>

或重复的其他变体。

下面是产生上述错误的子类的片段。

from PyQt5.QtNetwork import QNetworkAccessManager

class NetworkAccessManager(QNetworkAccessManager):
    def __init__(self, parent=None):
        super().__init__(parent=parent)

    def createRequest(self, op, req, outgoingData):
        reply = QNetworkAccessManager.createRequest(self, op, req, outgoingData)

        reply.data = b''

        reply.readyRead.connect(lambda reply=reply: self._on_reply_ready_read(reply))

        return reply

    def _on_reply_ready_read(self, reply):
        if reply.isReadable() and reply.isOpen() and reply.bytesAvailable():
            reply_data = b''
            bytes_available = reply.bytesAvailable()

            # I put this attribute when the QWebFrame unsupportedContent event is fired.
            if hasattr(reply, 'is_unsupported') and reply.is_unsupported:
                # When content is unsupported, webview does not call read. 
                # We call read and clear the buffer instead.
                # This works fine!
                reply_data = bytes(reply.read(bytes_available))
            else:
                # The problem resides here.
                # At certain times the buffer is not cleared, leading to duplication of data.
                reply.data += reply_data

0 个答案:

没有答案