2017-10-01 1 views
1

J'envoie une demande de publication pour télécharger un fichier sur un serveur, je souhaite attendre que la réponse revienne, au lieu de donner à QNetworkAccessManager une fonction de rappel à appeler lorsque la requête est terminée . Puis-je faire cela en utilisant QEventLoop dans PyQt5?Attendre une réponse de QNetworkRequest dans PyQt5

Voici le code:

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 

Note: Payload est juste une classe que j'utilise pour créer le corps qui sera envoyé.

Répondre

0

La solution la plus simple est de connecter le signal finished de la réponse à la fente quit de la boucle d'événement:

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

Cependant, une mise en œuvre plus saine d'esprit devrait intégrer un time-out:

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 :(')