Wie implementiere ich PyQGIS-Multithreading, um einen Fortschrittsbalken zu aktualisieren?

9

Ich entwickle ein PyQGIS-Plugin mit Python. Ich habe ein Problem bei der Implementierung des Threadings in meinem Plugin. Ich habe ein Python-Skript geschrieben, das eine Klasse enthält, die alle verwendeten Geoverarbeitungsmethoden umschließt. Das Problem, mit dem ich konfrontiert bin, ist die Verarbeitung der Methoden in Threads. Um ein besseres Bild meines Problems zu erhalten, habe ich eine Benutzeroberfläche, die die Methode calcNDVI()wie folgt aufruft :

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

Dieser Funktionsaufruf ruft eine calcNDVI () -Methode auf, die die ganze Magie ausführt und das Ergebnis einem QGIS-Projekt hinzufügt. Der Methodenaufruf ist auch mit der Übergabe einiger Argumente verbunden.

Ich habe viele Quellen durchgesehen, kann aber nicht verstehen, wie ich meine Algorithmen in einem Thread implementieren kann. Der Code, den ich durchlaufen habe, implementiert alles in der Ausführungsmethode, was es für mich schwierig macht, da in meiner Klasse mehr als eine Methode verarbeitet werden muss, und ich möchte auch, dass der Benutzer auswählen kann, welche Methode ausgeführt werden soll die Benutzeroberfläche.

Ich verarbeite Landsat-Datensätze, deren Verarbeitung zu lange dauert.

Milton Isaya
quelle

Antworten:

1

Implementieren Sie zunächst alle Ihre umfangreichen Berechnungen in einer QRunnable-Unterklasse. Weitere Informationen finden Sie hier ( http://pyqt.sourceforge.net/Docs/PyQt4/qrunnable.html ). Danach können Sie in Ihrer OK-Schaltfläche (oder in der Methode, mit der der Prozess gestartet wird) Folgendes tun:

    # 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)

Denken Sie daran, ein QThreadPool-Objekt zu erstellen, um Ihren Thread zu starten:

self.threadpool = QThreadPool()
lcoandrade
quelle