Hello. I already asked this on the PyQt mailing list but I guess it was not the right place; this is more of a Qt problem. I’m trying to implement a custom URI scheme handler, in a context where the underlying data will actually be fetched asynchronously. I reduced the problem to the « minimal » code pasted below (python 3.5, PyQt 5.8/Qt 5.8). Basically the problem is that when I call QWebEngineUrlRequestJob.reply() with an instance of my custom QIODevice, I expect the following:
1. bytesAvailable() is called, returns 0 (no data available yet) 2. The request job waits for readyRead to be emitted 3. The proceeds with bytesAvailable() / readData() until data is exhausted 4. Goto 2, until readChannelFinished is emitted What actually happens: 1. bytesAvailable() is called, returns 0 2. The request job tries to read 32 Kb nonetheless 3. It gets no data, closes the QIODevice Did I miss something here ? This happens on both mac OS and Linux. Didn’t try on Windows yet. TIA Jérôme Laheurte from PyQt5 import QtCore, QtWidgets from PyQt5.QtWebEngineWidgets import QWebEngineView from PyQt5.QtWebEngineCore import QWebEngineUrlSchemeHandler class TestIODevice(QtCore.QIODevice): def __init__(self): super().__init__() self.open(self.ReadOnly | self.Unbuffered) self._data = b'' QtCore.QTimer.singleShot(1000, self._dataReceived) def _dataReceived(self): print('== RECV') self._data = b'foo' self.readyRead.emit() def bytesAvailable(self): count = len(self._data) + super().bytesAvailable() print('== AVAIL', count) return count def isSequential(self): return True def readData(self, maxSize): print('== READ', maxSize) data, self._data = self._data[:maxSize], self._data[maxSize:] return data def close(self): print('== CLOSE') super().close() class TestHandler(QWebEngineUrlSchemeHandler): def requestStarted(self, request): self._dev = TestIODevice() # Must keep ref request.reply(b'text/plain', self._dev) class TestWindow(QtWidgets.QMainWindow): def __init__(self): super().__init__() self._view = QWebEngineView(self) self._handler = TestHandler() # Must keep ref self._view.page().profile().installUrlSchemeHandler(b'spam', self._handler) self._view.setHtml('<html><head><title>Test</title></head><body><img src="spam:eggs" /></body></html>') self.setCentralWidget(self._view) self.show() self.raise_() if __name__ == '__main__': app = QtWidgets.QApplication([]) win = TestWindow() app.exec_() _______________________________________________ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest