8

I am developing a PyQGIS plugin using python. I facing a problem during the implementation of threading in my plugin. I have written a Python script which contains a class wrapping all geo-processing methods in use. The problem I am facing is processing the methods in threads. To give a better picture of my problem, I have a UI which calls the method calcNDVI() as:

self.lst.calcNDVI(self.RedBand, self.NIRBand, None, self.outputRaster, self.sensorType, self.dataType, self.addToQGIS)

This function call, calls a calcNDVI() method which does all the magic and adds the result to a QGIS project. The method call is also associated with passing some arguments.

I have gone through many sources but I can't get to understand how I can implement my algorithms in a threaded way. The code I have come through implements everything in the run method which makes it difficult for me as I have more than one method to be processed in my class, and I would also like the user to be able to choose which method to be run through the UI.

I am processing Landsat datasets which take too much time to process.

1

First, implement all your heavy calculations in a QRunnable subclass. Take a look here to get more details (http://pyqt.sourceforge.net/Docs/PyQt4/qrunnable.html). After that in your ok button (or in the method that will start the process) you can do something like this:

    # Initiating processing
    task = ThreadTask(init parameters...)
    task.setParameters( your parameters here...)
    # Connect your signal here (somethig like this)
    task.signals.processFinished.connect(self.processFinished)
    task.signals.errorOccurred.connect(self.errorOccurred)
    task.signals.userCanceled.connect(self.userCanceled)
    # Setting the progress bar
    self.progressMessageBar = self.iface.messageBar().createMessage('Processing landsat image...')
    self.progressBar = QtGui.QProgressBar()
    self.progressBar.setAlignment(Qt.AlignLeft|Qt.AlignVCenter)
    self.progressMessageBar.layout().addWidget(self.progressBar)
    self.iface.messageBar().pushWidget(self.progressMessageBar, self.iface.messageBar().INFO)
    self.progressBar.setRange(0, 0)
    self.progressMessageBar.destroyed.connect(task.signals.cancel)
    # Starting process
    self.threadpool.start(task)

Remember to create a QThreadPool object to start your thread:

self.threadpool = QThreadPool()

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.