'PyQt5 QNetworkReply stops updating of continuous response when in signal handler

I'm trying to continuously get frames from this server:

def get_feed():
    while True:
        time.sleep(0.06)
        buffer = get_shot()
        buffer = buffer.tobytes()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n'
               b'Content-Length: ' + str(len(buffer)).encode() + '\r\n\r\n' + 
               buffer + b'\r\n')
               
               
@app.route('/', methods=['GET'])
def index():
    return Response(get_feed(), mimetype='multipart/x-mixed-replace; boundary=frame')

For that I use this code:

class ExampleApp(QtWidgets.QMainWindow, test.Ui_MainWindow):
    def __init__(self, parent=None):
        super(ExampleApp, self).__init__(parent)
        self.setupUi(self)
        
        self._source_url = QUrl("*link_here*")
        self._image_request = QNetworkRequest(self._source_url)
        self._network_manager = QNetworkAccessManager()
        self._image_reply = self._network_manager.get(self._image_request)
        ...

        self.frameTimer = QTimer(self)
        self.timeBetweenFrames = 1
        self.timeBetweenReads = 0.06
        self.frameTimer.timeout.connect(self.updateFrame)
        self.frameTimer.start(self.timeBetweenFrames)
        ...

    def updateFrame(self):
        # Get how many bytes do I need to read for the frame
        content_length = 0
        buff = self._image_reply.readAll()
        frameSizeAddress = buff.lastIndexOf(b'Content-Length:') + len(b'Content-Length: ')
        frameSizeEndAddress = buff[frameSizeAddress:].indexOf(b'\r\n')
        
        if frameSizeAddress == -1 or frameSizeEndAddress == -1:
            self.frameTimer.start(self.timeBetweenFrames)
            return
        
        frameSize = int(str(buff[frameSizeAddress:frameSizeAddress+frameSizeEndAddress], 'utf-8'))
        frameBegin = frameSizeAddress + frameSizeEndAddress + 4
        
        imageBuffer = buff[frameBegin:frameBegin+frameSize]
        readenBytes = len(imageBuffer)
        
        # If the image came partially
        while(readenBytes < frameSize):
            time.sleep(self.timeBetweenReads)
            buff = self._image_reply.read(frameSize-readenBytes)
            imageBuffer += buff[:frameSize-readenBytes]
            readenBytes = len(imageBuffer)
            print(len(buff))

And here comes the problem. If the image came partially it will never be read. Last print always give 0.

If use read(1024) instead of readAll() during first read here

content_length = 0
buff = self._image_reply.readAll()

Then everything works but if frames come faster then the app reads them: they begin stacking and delay between feed and display-image becomes bigger and bigger.

For me it looks like QNetworkReply doesn't update when it is in signal handler, so server do not write in it new bytes.

How can I solve this?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source