Tuesday, 12 March 2019

pyqgis - Usage of QgsTask and QgsTaskManager



I'm trying to test the new QgsTask and QgsTaskManager, I found some examples in the PullRequest in github. I modified it slightly and added a print(i) in the code bellow:


from qgis.core import QgsTask, QgsTaskManager
from time import sleep
import random
def run1(task,time):
wait_time = time / 100.0
sum = 0
iterations = 0
for i in range(101):
sleep(wait_time)

print(i)
# use task.setProgress to report progress
task.setProgress( i )
sum += random.randint(0,100)
iterations += 1
# check task.isCancelled() to handle cancellation
if task.isCancelled():
stopped()
return
# raise expections to abort task

#if random.randint(0,100) == 7:
# raise Exception('bad value!')
# use task object to store results of calculations or operations
task.result = [sum,iterations]

task=QgsTask.fromFunction('waste cpu', run1, 2)
mgr=QgsTaskManager()
mgr.addTask(task)
task.isFinished()


When I run this code in the Python console it returns 0 two times and then nothing more. I expected 101 printouts (0-100)? Afterwards I tried to see if it was finished with trying to call task.isFinished(), hence that gave me a RuntimeError: wrapped C/C++ object of type QgsTaskWrapper has been deleted.


In the end I would like use one QgsTask to run a time consuming script and one QgsTask to run a dialog (maybe a progressbar) telling the user that script is still running..


Any suggestion what I'm doing/thinking wrong or were to look at other examples?


EDIT: The problem was not only that there was two "L" in isCancel and start of QgsTaskManager, it was also that I tried to use print() within QgsTask. So I tried another approach with two GUIs that I tried in this repo.


EDIT: I updated the github Master repo using a QtTimer, still no 100% success, hence the branch without QgsTask is working as expected. But I really want to understand how QgsTask is to be implemented..



Answer



I kind of made it :) I can run this once, hence when I tries to do it a second time it fails and I need to print(1) in run_counting. The project is uploaded to https://github.com/axelande/QgisTest


def run_counting(self):
counting = int(self.dlg.LESeconds.text())
counting_test = CountingTest()

task1 = QgsTask.fromFunction('counting', counting_test.run_count,
counting,
on_finished=self.stop_from_counting)
waiting_msg = WaitingMsg()
task2 = QgsTask.fromFunction('waiting', waiting_msg.run)
self.tsk_mngr.addTask(task1)
print(1) #This is required but I don't know why?
self.tsk_mngr.addTask(task2)

The classes CountingTest and WaitingMsg requires a sleep that is longer than the QtTimer timer.



class WaitingMsg(QtWidgets.QDialog, FORM_CLASS):
def __init__(self, parent=None):
"""Constructor."""
super(WaitingMsg, self).__init__(parent)
self.setupUi(self)
self.cancel_is_set = False
self.task = None
self.my_timer = None

def set_cancel(self):

if self.task.isCanceled():
self.done(0)

def run(self, task):
self.task = task
self.show()
self.my_timer = QtCore.QTimer(self)
self.my_timer.timeout.connect(self.set_cancel)
self.my_timer.start(500) # 1 sec intervall
sleep(.6)

self.exec_()
self.done(0)

class CountingTest(QtWidgets.QDialog, FORM_CLASS):
def __init__(self, parent=None):
"""Constructor."""
super(CountingTest, self).__init__(parent)
self.setupUi(self)
self.my_timer = None
self.task = None

self.counting = None
self.t0 = None

def _update_text(self):
tid = int(time() - self.t0)
self.LSeconds.setText(str(tid))
self.update()
if tid == self.counting:
self.done(0)
return self.counting


def run_count(self, task, counting):
self.counting = int(counting)
print(counting)
self.t0 = time()
self.task = task
self.show()
self.my_timer = QtCore.QTimer(self)
self.my_timer.timeout.connect(self._update_text)
self.my_timer.start(1000) # 1 sec interval

sleep(1.1)
self.exec_()
self.done(0)
return counting

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...