QGIS – Usage of QgsTask and QgsTaskManager

pyqgispyqtqgis-3

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..

Best Answer

There's a typo in that script - it should be isCanceled() (one l, not two)

You should also add your task to the global task manager instead of creating a new manager:

QgsApplication.taskManager().addTask(task)

One thing to be very careful about is never to create widgets or alter gui in a task. This is a strict Qt guideline - gui must never be altered outside of the main thread. So your progress dialog must operate on the main thread, connecting to the progress report signals from the task which operates in the background thread.

Related Question