2

I have a python plugin targeting QGIS 1.8 that uses QgsNetworkAccessManager and QNetworkRequest to issue a GetCapabilities request to WMS servers.

With 1.8 everything was working fine. Now we are porting this plugin to QGIS 2.x (tested on 2.6 and 2.7 of 16/02/2015) and have found that some errors are being displayed.

As far as our python code can tell everything is working as expected, however 20 seconds after a network request is initiated a "Network request ... timed out" message is displayed in the messages log and in a banner at the top of the map pane.


I have created a minimal example that can be copy/pasted into the python console:

from datetime import datetime
from PyQt4.QtCore import SIGNAL, QUrl
from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest

def request_download():
    global reply
    manager = QgsNetworkAccessManager.instance()
    url = QUrl("http://www.example.net")
    request = QNetworkRequest(url)
    print "Download start time: {}".format(datetime.now())
    reply = manager.createRequest(QNetworkAccessManager.GetOperation, request)
    reply.connect(reply, SIGNAL("finished()"), handle_download)

def handle_download():
    global reply
    print "Download finish time: {}".format(datetime.now())
    print "Finished: {}".format(reply.isFinished())
    print "Bytes received: {}".format(len(reply.readAll()))

request_download()

# python console:
#   Download start time: 2015-02-23 15:24:39.887000
#   Download finish time: 2015-02-23 15:24:41.077000
#   Finished: True
#   Bytes received: 1270
# 
# message log:
#   2015-02-23T15:25:01    1    Network request http://www.example.com timed out

As this example shows the download appears to succeed:

  1. The finish() signal is emitted.
  2. The reply.isFinished() method returns True.
  3. The reply.readAll() method returns the correct data.

However the time out error message is displayed :

  1. Prominently on a yellow banner at the top of the map pane.
  2. Under the Network tab on the Log Messages panel.

How do I perform a download without triggering this error?

  • I approached this problem month ago... I remember there wheren't solution other than popping out the message from QgsMessageBar, because the timeout was sent from a part of the qgis.core. Now I don't remember why and in what conditions there where that message (I should re-read the qgis code). I don't know if it is changed in master. Please file a issue if it can be considered an error. – Luigi Pirelli Feb 23 '15 at 12:38
2

If you are fine with a solution that uses QNetworkAccessManager from Qt (instead of the manager from QGIS libs), you can do it this way:

from datetime import datetime
from PyQt4.QtCore import QUrl
from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest

def request_download(manager):
    url = QUrl("http://www.geotux.tuxfamily.org")
    request = QNetworkRequest(url)
    print "Download start time: {}".format(datetime.now())
    manager.get( request )

def handle_download(reply):
    print "Download finish time: {}".format(datetime.now())
    print "Finished: {}".format(reply.isFinished())
    print "Bytes received: {}".format(len(reply.readAll()))

manager = QNetworkAccessManager()
manager.finished.connect( handle_download )
request_download(manager)

As you can see, you don't need to use global variables.


BTW, I couldn't use your code from a QGIS Python console, it threw this error: RuntimeError: no access to protected functions or signals for objects not created from Python

  • 1
    Thanks, looks good I will try it out at work in the morning. – Kelly Thomas Feb 23 '15 at 14:53
  • The RuntimeError surprises me, what OS and qgis version are you using? – Kelly Thomas Feb 23 '15 at 14:58
  • Yes, first time I see it. QGIS v.2.8 on a GNU/Linux (Mint). – Germán Carrillo Feb 23 '15 at 15:06
  • Thanks, that works great. One gotcha I will warn readers about is that it is important that the QNetworkAccessManager instance has a lifetime that spans the duration of the network transaction. – Kelly Thomas Feb 24 '15 at 2:31
  • @GermánCarrillo: And how would you manage to use the reply outside of handle_download? After the call request_download for example... – m13r Jun 10 '16 at 11:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.