In keeping with Setting up thread with busy progress indicator or GIF in PyQGIS where I asked about thread and busy indicator I now wish to ask understand how it is possible to use a variable declared in an instance of a Qgstask in another Qgstask?
In the code below I tried to use the output of the native 'centroid' QGIS tool as the input of the buffering tool used in another Qgstask. I've done a lot of researches on internet but I don't find any examples about my problem.
from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication
from qgis.PyQt.QtGui import *
from qgis.PyQt.QtWidgets import *
from datetime import datetime
import os.path, os, shutil
from qgis.core import *
from qgis.gui import *
from qgis.utils import *
import processing
from PyQt5.QtCore import pyqtSignal
class MyTask(QgsTask):
messaging = pyqtSignal(str)
result = pyqtSignal(dict)
def __init__(self, layer):
super(MyTask, self).__init__()
self.layer = layer
def run(self):
start = datetime.now()
# buffer
alg_params = {
'ALL_PARTS': True,
'INPUT': self.layer,
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
self.centroid = processing.run('native:centroids', alg_params)
end = datetime.now()
buffer_info = "Making centroids..."
buffer_title = '<center><h3><span style=\" color: #7eb346; font-weight:bold\">%s</span></h3></center>' % buffer_info
self.messaging.emit(buffer_title)
self.messaging.emit(
"Time required to achieve the 1st task: " + str((end - start).total_seconds()) + " seconds" + "\n")
return True
class MyTask2(QgsTask):
messaging = pyqtSignal(str)
result = pyqtSignal(dict)
def __init__(self, centroid):
super(MyTask2, self).__init__()
self.centroid = centroid
def run(self):
start2 = datetime.now()
# buffer
alg_params = {
'DISSOLVE': True,
'DISTANCE': 100,
'END_CAP_STYLE': 0,
'INPUT': self.centroid['OUTPUT'],
'JOIN_STYLE': 0,
'MITER_LIMIT': 2,
'SEGMENTS': 5,
'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
buffer = processing.runAndLoadResults('native:buffer', alg_params)
end2 = datetime.now()
buffer_info = "Layer Buffering..."
buffer_title = '<center><h3><span style=\" color: #7eb346; font-weight:bold\">%s</span></h3></center>' % buffer_info
self.messaging.emit(buffer_title)
self.messaging.emit("Time required to achieve the task: " + str((end2 - start2).total_seconds()) + " seconds" + "\n")
return True
class plugintestDialog(QDialog):
def __init__(self, parent=None):
super(plugintestDialog, self).__init__(parent)
self.lyt = QVBoxLayout(self)
self.pushButton = QPushButton("Test 1", self)
self.progressbar = QProgressBar(self)
self.progressbar.setMinimum(0)
self.lyt.addWidget(self.pushButton)
self.lyt.addWidget(self.progressbar)
class plugintest:
messaging = pyqtSignal(str)
def __init__(self, iface):
self.iface = iface
self.dlg = plugintestDialog()
self.dlg.pushButton.clicked.connect(self.centroid)
def run(self):
self.dlg.show()
result = self.dlg.exec_()
def centroid(self):
# disable pushbutton for avoid multi-clicks
self.dlg.pushButton.setEnabled(False)
# start the busy state of the progressbar
self.dlg.progressbar.setMaximum(0)
# define the layer to process (just comment / uncomment what you want)
self.layer = QgsProject.instance().mapLayersByName('layer')[0]
# self.layer = self.dlg.mMapLayerComboBox.currentLayer()
# create a new task
self.buffer_task = MyTask(self.layer)
# connect the signals
self.centroid_task.messaging.connect(lambda t: print(t))
self.centroid_task.taskCompleted.connect(self.buffering)
# launch the processing of the task
QgsApplication.taskManager().addTask(self.centroid_task)
def buffering(self):
self.centroid= self.centroid['OUTPUT']
self.buffer_task = MyTask2(self.centroid)
# connect the signals
self.buffer_task.messaging.connect(lambda t: print(t))
self.buffer_task.taskCompleted.connect(self.buffering_completed)
# launch the processing of the task
QgsApplication.taskManager().addTask(self.buffer_task)
def buffering_completed(self):
self.dlg.progressbar.setMaximum(1)
self.buffer_task.disconnect()
self.dlg.pushButton.setEnabled(True)
my_instance = plugintest(iface)
my_instance.run()
result
to emit the processing result and connect this task signal toadd_map_layer
method.add_map_layer
but what if I don't want to add the centroid layer ? Is there a way to fetch the centroid output directly (without creating a new function for this purpose) ?