Como implementar o multithreading do PyQGIS para atualizar uma barra de progresso

9

Estou desenvolvendo um plugin PyQGIS usando python. Estou enfrentando um problema durante a implementação do encadeamento no meu plugin. Eu escrevi um script Python que contém uma classe que envolve todos os métodos de processamento geográfico em uso. O problema que estou enfrentando é processar os métodos em threads. Para dar uma ideia melhor do meu problema, tenho uma interface do usuário que chama o método calcNDVI()como:

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

Essa chamada de função chama um método calcNDVI () que faz toda a mágica e adiciona o resultado a um projeto QGIS. A chamada de método também está associada à passagem de alguns argumentos.

Passei por muitas fontes, mas não consigo entender como implementar meus algoritmos de maneira encadeada. O código que obtive implementa tudo no método run, o que dificulta para mim, pois tenho mais de um método a ser processado em minha classe e também gostaria que o usuário pudesse escolher qual método executar. a interface do usuário.

Estou processando conjuntos de dados Landsat que levam muito tempo para serem processados.

Milton Isaya
fonte

Respostas:

1

Primeiro, implemente todos os seus cálculos pesados ​​em uma subclasse QRunnable. Dê uma olhada aqui para obter mais detalhes ( http://pyqt.sourceforge.net/Docs/PyQt4/qrunnable.html ). Depois disso, no botão ok (ou no método que iniciará o processo), você poderá fazer algo assim:

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

Lembre-se de criar um objeto QThreadPool para iniciar seu thread:

self.threadpool = QThreadPool()
lcoandrade
fonte