等待PyQt5中QNetworkRequest的响应

时间:2017-10-01 12:14:10

标签: python qt pyqt pyqt5

我发送一个帖子请求将文件上传到服务器,我想等待响应回来,而不是给QNetworkAccessManager一个回调函数来在请求完成时调用。 我可以在PyQt5中使用QEventLoop吗?

以下是代码:

    def qt_request(self, method, url, files=None, body=None, headers=None,
               progress_callback=None):
    try:
        self._init_manager()
        net_request = QNetworkRequest(QUrl(url))
        payload_obj = RequestHandler.Payload()
        reply = None
        net_request.setHeader(QNetworkRequest.ContentTypeHeader,
                              "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW")
        if headers is None:
            headers = {}
        if files is not None:
            for key, value in files.items():
                payload_obj.add_files_to_payload(key, value)
        if body is not None:
            for key, value in body.items():
                payload_obj.add_to_payload(key, value)
        for key, value in headers.items():
            net_request.setRawHeader(bytes(key, "utf-8"), bytes(value, "utf-8"))
        loop = QEventLoop()
        if method == "POST":
            reply = self._manager.post(net_request, payload_obj.get_pay_load())
        elif method == "GET":
            reply = self._manager.get(net_request)
        if progress_callback is not None:
            reply.uploadProgress.connect(progress_callback)
        self._progress_message = Message("Uploading started...", dismissable=False, lifetime=0)
        self._progress_message.show()
        loop.exec()
        self._progress_message.hide()
        self._progress_message = None
        self._progress_message = Message("Uploading finished...", dismissable=False, lifetime=0)
        self._progress_message.show()
        return reply.readAll()
    except Exception as e:
        if self._progress_message:
            self._progress_message.hide()
            self._progress_message = None
        self._progress_message = Message("Exception: %s" % str(e), dismissable=True, lifetime=0)
        self._progress_message.show()
        raise e

注意:Payload只是我用来创建将要发送的主体的类。

1 个答案:

答案 0 :(得分:0)

最简单的解决方案是将回复的finished信号连接到事件循环的quit位置:

loop = QEventLoop()
# get reply object ...
reply.finished.connect(loop.quit)
print('fetching request...')
loop.exec_()

但是,更合理的实现应该包含超时:

loop = QtCore.QEventLoop()
timer = QtCore.QTimer()
timer.setSingleShot(True)
timer.timeout.connect(lambda: loop.exit(1))
timer.start(10000) # 10 second time-out
# get reply object ...
reply.finished.connect(loop.quit)
print('fetching request...')
if loop.exec_() == 0:
    timer.stop()
    print('received: ', reply.readAll().count())
else:
    print('request timed-out :(')