Geographic Information Systems Asked on April 21, 2021
I am trying to implement QgsTasks into a PlugIn to keep its GUI responsive while running. I have studied the docs at https://docs.qgis.org/3.16/en/docs/pyqgis_developer_cookbook/tasks.html, which unfortunately does not cover such a case in its examples and my Python skills are obviously too low to adapt these examples to my usecase. Also I have studied similar questions like Rewriting QgsTask abstract class? and How to use Threads in PyQgis, mainly to keep UI active? and Usage of QgsTask and QgsTaskManager and How do I maintain a resposive GUI using QThread with PyQGIS.
However, from these docs I dont understand how to implement it properly to run a function of a PlugIn as a task with all its benefits.
Currently, I am focusing my QgsTask experiments on QgsTask.fromFunction(). I have narrowed down my code to:
# imports ...
MESSAGE_CATEGORY = 'My Plugin'
class MyPlugin():
def __init__(self, iface):
# standard content by plugin builder
def add_action()#standard
# standard content by plugin builder
def unload(self):
# standard content by plugin builder
def do_some_work(self):
QgsMessageLog.logMessage("starting worker",MESSAGE_CATEGORY,Qgis.Info)
QgsMessageLog.logMessage("before var",MESSAGE_CATEGORY,Qgis.Warning)
inputlayer_numberoffields = self.selectedlayer.fields().count() # Function started from class_task crashes here, can not read variable
QgsMessageLog.logMessage("after var",MESSAGE_CATEGORY,Qgis.Warning)
# do heavy work
def maplayerselection(self):
self.selectedlayer = self.dlg.MyQgsMapLayerComboBox.currentLayer()
def run(self):
if self.first_start == True:
self.first_start = False
self.dlg = MyPluginDialog()
self.maplayerselection()
self.dlg.StartButton.clicked.connect(self.start_work_as_task) # See below
#self.dlg.StartButton.clicked.connect(self.do_some_work) # Everything works fine. Can be started multiple times. Gui not responsive while running
self.dlg.MyQgsMapLayerComboBox.currentIndexChanged.connect(self.maplayerselection)
self.dlg.show()
result = self.dlg.exec_()
#class_task = QgsTask.fromFunction('Do something', do_some_work)
def start_work_as_task(self):
QgsMessageLog.logMessage("start_work_as_task before starting worker",MESSAGE_CATEGORY,Qgis.Warning)
function_task = QgsTask.fromFunction('Do something', self.do_some_work())
QgsApplication.taskManager().addTask(function_task) # Starts worker function and runs correctly, but does not bring any benefits (a responsive Gui), only disadvantages like crash on second start
#QgsApplication.taskManager().addTask(self.class_task) # Starts worker function but does not run correctly. Worker function can not read variables from other functions
QgsMessageLog.logMessage("start_work_as_task running after starting worker",MESSAGE_CATEGORY,Qgis.Warning)
My "working" implementation (function_task
) unfortunately does not bring the expected advantage of a responsive GUI. What am I doing wrong here?
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP