4

I want to force closing Qgis project (QgsTask) in some point

NOTE:
QgsProject.instance().clear() # NOT WORKING

QgsTaskManager().cancelAll() # NOT WORKING

QgsTask.cancel() # NOT WORKING

task.canCancel() # FALSE

project = QgsProject.instance()
project.clear() # NOT WORKING
QgsTaskManager().cancelAll() # NOT WORKING
tasks = QgsApplication.taskManager().activeTasks()
for task in tasks:
    print (task.canCancel()) # False
    print (task.description()) # Loading “C:/Users/User/Desktop/some_project.qgs”
    print (task.flags()) # <qgis._core.QgsTask.Flags object at 0x000002330527E4C8>

    task.cancel() # NOT WORKING

Is there any way to force closing project or task or change flag QgsTask.CanCancel to True ?

5
  • duplicate gis.stackexchange.com/questions/318503/…
    – Fran Raga
    Apr 12, 2019 at 9:58
  • that is also my question (without answer). I separate problem, a little bit simplify it, because I made some progress @FranRaga
    – ncica
    Apr 12, 2019 at 10:01
  • when you created the task did you put the flag canCancel?
    – Fran Raga
    Apr 12, 2019 at 10:55
  • No :/ I just open the project : Project -> open... @FranRaga
    – ncica
    Apr 12, 2019 at 10:57
  • Add sample creating task object
    – Fran Raga
    Apr 12, 2019 at 11:01

2 Answers 2

2

I add an example of a task to load a project, For cancel only uncomment

task.cancel()

Sample

def completed(exception, result=None):
    if exception is None:
        if result is None:
            print('Completed with no exception and no result probably manually canceled by the user')
        else:
            print("completed " , result['task'])
            # But layers not show on canvas and refresh not work
            # Trick (probably don't know the right method)
            root = QgsProject.instance().layerTreeRoot()
            layers =  QgsProject.instance().mapLayers()
            map_canvas_layer_list = [l for l in layers.values()]
            for layer in map_canvas_layer_list:
                node=root.findLayer( layer.id())
                v=node.isVisible ()
                node.setItemVisibilityChecked(not v)
                node.setItemVisibilityChecked(v)
                break
    else:
        print ("Failed Task")
        raise exception

def LoadProject(task,mFile):
    project = QgsProject.instance()
    project.read(mFile)
    return {'task': task.description()}

mFile = r'D:\sample.qgs'
task = QgsTask.fromFunction("Loading project",LoadProject,mFile=mFile,on_finished=completed, flags=QgsTask.CanCancel)

QgsApplication.taskManager().addTask(task)

# task.cancel() # For cancel , uncomment if you want cancel it
while QgsApplication.taskManager().countActiveTasks() > 0:
    QCoreApplication.processEvents()

Note: I suppose there is a method to make them visible, but I thought of that as a trick

tested QGIS 3.6.1

I hope it helps you

1

There is a bit more to it, first of all the CanCancel flag must be set.

task = QgsTask.fromFunction("Name",some_method,on_finished=completed, flags=QgsTask.CanCancel)

Now by calling:

task.cancel()

All you do is:

void QgsTask::cancel ( )

Notifies the task that it should terminate.

Calling this is not guaranteed to immediately end the task, rather it sets the isCanceled() flag which task subclasses can check and terminate their operations at an appropriate time. Any subtasks owned by this task will also be canceled. Derived classes must ensure that the base class implementation is called from any overridden version.

In other words calling cancel() just sets the isCanceled() flag for task and it's subtasks, and it is up to the developer to periodically check for this flag to allow the execution of cancelling. Otherwise task goes happily on ever after. E.g. after and before every bigger part in method there must be lines:

if task.isCanceled():
    return 'Ending method here as task is cancelled.'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.