2

I'm developing a QGIS plugin that has the functionality to download raster files from a server. As the final step, the user has to name the file and select a file path on their system. After that, a download to said location using QgsFileDownloader commences. The downloader should simply download the file when called to the given location and then delete itself automatically. The following script works perfectly when run in QGIS's own editor:

#file_name houses the path selected by user
file_name, filter = (QFileDialog.getSaveFileName(iface.mainWindow(), 
                        "Save the layer", filter='Virtual file (*vrt)'))
url = QUrl("http://dummypath/to/server/file.tif")

# functions triggered when download either succeeds or fails
def downloadFailed(error):
    print(error)
def downloadSucceeded():
    print('success')

downloader = QgsFileDownloader(url, file_name, delayStart=True)

# connecting signals to functions
downloader.downloadError.connect(downloadFailed)
downloader.downloadCompleted.connect(downloadSucceeded)

downloader.startDownload()

However, when I implement that script to my plugin, it errors every time. The code works identically except that it's called from another function and that successful download triggers another function instead of just a print statement. Here's what I mean:

def getData(self):
    # things happen...
    # ...
    self.saveData(url)

def downloadFailed(self, error):
    print(error)

def downloadSucceeded(self):
    # calls another function
    self.addLayerToQgis(self.file_name)

def saveData(self, url, file_format):
    self.file_name, file_filter = QFileDialog.getSaveFileName(self.dlg,
                                "Save the layer", filter='Selected format (*'+file_format+')')

    qt_url = QUrl(url)

    downloader = QgsFileDownloader(qt_url, self.file_name)
    downloader.downloadError.connect(self.downloadFailed)
    downloader.downloadCompleted.connect(self.downloadSucceeded)
    downloader.startDownload()

This always ends in error with the following statement:

['Download failed: Operation canceled']

I don't quite understand why this happens. If I stop the code from proceeding after startDownload call, it works as intended. I mean this:

def saveData(self, url, file_format):
    # code...
    downloader.startDownload()
    raise NotImplementedError

Now the file gets downloaded without a hitch. I need to do things after the download, however. Does anyone know why the file downloader behaves like this?

  • 1
    You can use the Processing algorithm which is easier instead of the Qgs class. But if really want to use the Qgs class, you can have a look to my plugin: github.com/3liz/QuickOSM/blob/master/core/api/… which works well. AFAIK, you need to use a QEventLoop but I can't see one in your code. – etrimaille Jul 5 '19 at 9:54
  • Thank you! I need to read a bit on event loops (I'm fairly new to PyQGIS and programming in general), but this does seem to fix the issue based on a quick test. – tle Jul 5 '19 at 10:12

Your Answer

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

Browse other questions tagged or ask your own question.