• About plugins
  • QGIS Layer Definition File
  • New Plugins
  • Updated Plugins
  • Experimental
  • Top downloads
  • QGIS Server plugins

Plugin Tags

Qgis python plugins repository,  download latest, task manager.

Assign feature to a given user

Assign a feature to a given user. It depends on a PostgreSQL dabase that contains the user names.

Sustaining Members

task manager qgis

Gold Sponsor

task manager qgis

Silver Sponsors

Sustaining member logos

Tasks - doing heavy work in the background ¶

Introduction ¶.

Background processing using threads is a way to maintain a responsive user interface when heavy processing is going on. Tasks can be used to achieve threading in QGIS.

A task ( QgsTask ) is a container for the code to be performed in the background, and the task manager ( QgsTaskManager ) is used to control the running of the tasks. These classes simplify background processing in QGIS by providing mechanisms for signaling, progress reporting and access to the status for background processes. Tasks can be grouped using subtasks.

The global task manager (found with QgsApplication.taskManager() ) is normally used. This means that your tasks may not be the only tasks that are controlled by the task manager.

There are several ways to create a QGIS task:

Create your own task by extending QgsTask

Create a task from a function

Create a task from a processing algorithm

Any background task (regardless of how it is created) must NEVER perform any GUI based operations, such as creating new widgets or interacting with existing widgets. Qt widgets must only be accessed or modified from the main thread. Attempting to use them from background threads will result in crashes.

Dependencies between tasks can be described using the addSubTask function of QgsTask . When a dependency is stated, the task manager will automatically determine how these dependencies will be executed. Wherever possible dependencies will be executed in parallel in order to satisfy them as quickly as possible. If a task on which another task depends is canceled, the dependent task will also be canceled. Circular dependencies can make deadlocks possible, so be careful.

If a task depends on a layer being available, this can be stated using the setDependentLayers function of QgsTask . If a layer on which a task depends is not available, the task will be canceled.

Once the task has been created it can be scheduled for running using the addTask function of the task manager. Adding a task to the manager automatically transfers ownership of that task to the manager, and the manager will cleanup and delete tasks after they have executed. The scheduling of the tasks is influenced by the task priority, which is set in addTask .

The status of tasks can be monitored using QgsTask and QgsTaskManager signals and functions.

Extending QgsTask ¶

In this example RandomIntegerSumTask extends QgsTask and will generate 100 random integers between 0 and 500 during a specified period of time. If the random number is 42, the task is aborted and an exception is raised. Several instances of RandomIntegerSumTask (with subtasks) are generated and added to the task manager, demonstrating two types of dependencies.

Task from function ¶

Create a task from a function ( doSomething in this example). The first parameter of the function will hold the QgsTask for the function. An important (named) parameter is on_finished , that specifies a function that will be called when the task has completed. The doSomething function in this example has an additional named parameter wait_time .

Task from a processing algorithm ¶

Create a task that uses the algorithm qgis:randompointsinextent to generate 50000 random points inside a specified extent. The result is added to the project in a safe way.

See also: https://www.opengis.ch/2018/06/22/threads-in-pyqgis3/ .

Task manager for managing a set of long-running QgsTask tasks. More...

#include < qgstaskmanager.h >

Inheritance graph

Detailed Description

Task manager for managing a set of long-running QgsTask tasks.

This class can be created directly, or accessed via QgsApplication::taskManager() .

Definition at line 392 of file qgstaskmanager.h .

Constructor & Destructor Documentation

◆  qgstaskmanager().

Constructor for QgsTaskManager .

Definition at line 390 of file qgstaskmanager.cpp .

◆  ~QgsTaskManager()

Definition at line 397 of file qgstaskmanager.cpp .

Member Function Documentation

◆  activetasks().

Returns a list of the active (queued or running) tasks.

Definition at line 654 of file qgstaskmanager.cpp .

◆  addTask() [1/2]

Adds a task to the manager, using a full task definition (including dependency handling).

Ownership of the task is transferred to the manager, and the task manager will be responsible for starting the task. The priority argument can be used to control the run queue's order of execution, with larger numbers taking precedence over lower priority numbers.

Definition at line 421 of file qgstaskmanager.cpp .

◆  addTask() [2/2]

Adds a task to the manager.

Definition at line 416 of file qgstaskmanager.cpp .

◆  allTasksFinished

Emitted when all tasks are complete.

◆  cancelAll()

Instructs all tasks tracked by the manager to terminate.

Individual tasks may take some time to cancel, or may totally ignore this instruction. Calling this does not block but will instead signal the tasks to cancel and then return immediately.

Definition at line 542 of file qgstaskmanager.cpp .

◆  count()

Returns the number of tasks tracked by the manager.

Definition at line 519 of file qgstaskmanager.cpp .

◆  countActiveTasks()

Returns the number of active (queued or running) tasks.

The includeHidden argument dictates whether hidden tasks should be shown.

Definition at line 662 of file qgstaskmanager.cpp .

◆  countActiveTasksChanged

Emitted when the number of active tasks changes.

◆  dependencies()

Returns the set of task IDs on which a task is dependent.

Definition at line 576 of file qgstaskmanager.cpp .

◆  dependenciesSatisfied()

Returns true if all dependencies for the specified task are satisfied.

Definition at line 556 of file qgstaskmanager.cpp .

◆  dependentLayers()

Returns a list of layers on which as task is dependent.

The task will automatically be canceled if any of these layers are about to be removed.

Definition at line 631 of file qgstaskmanager.cpp .

◆  finalTaskProgressChanged

Will be emitted when only a single task remains to complete and that task has reported a progress change.

◆  progressChanged

Will be emitted when a task reports a progress change.

◆  statusChanged

Will be emitted when a task reports a status change.

◆  task()

Returns the task with matching ID.

Definition at line 504 of file qgstaskmanager.cpp .

◆  taskAboutToBeDeleted

Emitted when a task is about to be deleted.

◆  taskAdded

Emitted when a new task has been added to the manager.

◆  taskId()

Returns the unique task ID corresponding to a task managed by the class.

Definition at line 525 of file qgstaskmanager.cpp .

◆  tasks()

Returns all tasks tracked by the manager.

Definition at line 513 of file qgstaskmanager.cpp .

◆  tasksDependentOnLayer()

Returns a list of tasks which depend on a layer.

Definition at line 637 of file qgstaskmanager.cpp .

◆  taskTriggered

Emitted when a task is triggered.

This occurs when a user clicks on the task from the QGIS GUI, and can be used to show detailed progress reports or re-open a related dialog.

◆  triggerTask

Triggers a task, e.g.

as a result of a GUI interaction.

Definition at line 682 of file qgstaskmanager.cpp .

Friends And Related Function Documentation

◆  testqgstaskmanager.

Definition at line 648 of file qgstaskmanager.h .

task manager qgis

de_DE

QGIS 3 Plugin Tutorial – Background Processing with QgsTask

task manager qgis

QGIS Tutorials

This tutorial is part of our QGIS tutorial series:

QGIS Tasks – background processing

In this tutorial you'll build a plugin which downloads and displays Mapzen Terrain Tiles , within the extents of a user-defined polygon layer. This download task can be enormous: the planet-wide dataset weighs ~ 1.5 TB. If the main plugin code simply calls a download function, QGIS would freeze for multiple minutes. This is where the QGIS background tasks ( QgsTask ) come in very handy. You can start a QgsTask which will run in another thread, keeping the main thread with QGIS reactive for the user.

The final plugin code can be found here . We assume that you are familiar with PyQGIS and the basics of plugin development in QGIS. In case you want to catch up on the latter, please refer to our QGIS plugin development guide .

Disclaimer Validity only confirmed for Linux , Mac OS and QGIS v3.20.2

Prerequisites

Hard prerequisites.

Recommendations

First we need to build the UI with Qt Designer. We won't cover any of the basics here, refer to our Qt Designer tutorial if you need a refresher.

The final plugin will look something like this:

To make sure we're on the same page along the code examples:

You can go ahead, create the UI file in Qt Designer, convert it to a Python file with pyuic5 and do the usual boilerplate code to get the plugin loadable by QGIS. You can always double-check with our solution when in doubt. Our minimal layout looks like this, with plugin.py holding our plugin's main class and gui and core being packages we'll add further files to further down:

Our plugin.py is pretty standard:

2 Collect the input

2.1 make the ui usable.

Before we start off with the more interesting part of designing the background task, we first have to know which elevation tiles we actually need to download. So we'll have to add some logic to the UI we just built.

Create a file gui/tile_elevation_dlg.py to hold that logic. As always we need a class which subclasses what we import from the output of pyuic5 . Don't be suprised by all the imports, we'll need them along the way:

This should be quite self-explanatory: when the user hits the "Download" button it will invoke the download_tiles() function, which we still need to define.

2.2 Collecting tiles to download

Before we start out, we have to know how those terrain tiles can be actually accessed. They're hosted on AWS Open Data infrastructure (the only thing you should use AWS for!), an example URL is http://s3.amazonaws.com/elevation-tiles-prod/skadi/N49/N49W097.hgt.gz . The tiles' size is 1° x 1° in WGS84. The base URL is http://s3.amazonaws.com/elevation-tiles-prod/skadi , then a folder collects all 360 longitudinal tiles for that latitude (here N49 ), while the file name denotes the lat/lon of the lower-left corner of the tile.

We'll want to collect all tiles which are covered by input polygon features, so let's see what that'd look like:

For all user-defined polygon features, we transform them to WGS84 and collect a set (to avoid duplicates) of all tiles whose bounding box intersect with the polygons' bounding boxes. If we couldn't find any intersecting tiles we notify the user and abort.

2.3 User feedback

Since the download could be potentially huge, we'd like to inform the user about the progress. The best communication way is via fairly unobtrusive messages in the pop-up message bar on top of the map canvas. That message bar does not only accept text to display but even other widgets, such as a progress bar:

Before we show you how we'll update the progress bar, we'll first create our QgsTask .

3 The QgsTask

Generally, there are three ways in which tasks can be created:

Our task is a little bigger and we like things to be encapsulated, so we chose to extend QgsTask . There is a bunch of functions you will need to override/implement when subclassing QgsTask :

3.1 Extending QgsTask

We start by creating a new Python module task.py inside a new package called core . Here, we subclass QgsTask :

The task needs the pre-computed grid of elevation tile bboxes and the directory where the user wants to store all those tiles. Also note the exception attribute here: since it's not safe to raise exceptions in a background task (this will crash QGIS), we initialize an empty exception instance attribute here, where we will store any exception that we catch in run() .

Now we can get to the actual task logic, implemented inside run() :

The logic of the actual heavy lifting inside run() works as follows: for every box in the elevation tile grid, we get the southwestern-most coordinates (their base lat/lon), from which the directory and tile names are created, as well as the URL to download the tile from. If the file does not exist yet, we download it, extract the .gz file in-memory and save the result into the respective directory.

The run() method of a QgsTask always needs to return a boolean value, which is used in finished() to evaluate whether the task ran successfully. After initializing the QgsNetworkAccessManager , which is used for handling the HTTP requests, we wrap the remainder of the method inside a try / except block to prevent exceptions from being raised. If an exception is caught, we save it and return False . In order to give the user control over cancelling the download, we check self.isCanceled() after each iteration, and return False if the user has canceled the task.

Next up is the finished() method:

Here, we want to handle three different cases:

In the first two cases, we only want to communicate the task outcome to the user. Remember that inside finished() , we can access objects from the main thread again, so we can simply push a message to the main interface's message bar. For the third case, we communicate the successful completion of the task to the user and additionally add the downloaded tiles to the map canvas.

3.2 Wrap up: user feedback and running the task

Lastly, we want to update the progress bar while the tiles are downloading. Remember that we can't directly access the widget we created earlier in gui/tile_elevation_dlg.py from within a running QgsTask , but luckily, QgsTask comes with a set of signals we can use to communicate with the user while the background task is running. progressChanged is the most important one here: we can emit it by calling self.setProgress(int) , where int is an integer between 0 - 100, indicating the tasks progress in percent. We connect to the signal in gui/tile_elevation_dlg.py right after initializing the task, and to the taskCompleted signal to clear the message bar again after the task has run:

Note that it's vital to assign the task not just to a variable, but to a class attribute. Otherwise, the task will be deleted after download_tiles() finishes, but before the task itself finishes.

Finally, the task needs to be run. For this, we use the QgsTaskManager , which is a singleton class that takes care of delegating any background tasks. We add the task and the task manager makes sure that the task starts running.

And that's it! We have successfully created a small plugin that downloads Mapzen/Tilezen elevation tiles in the background by using QgsTask , so that the user can continue interacting with QGIS while the download runs.

ALL ABOARD! JOIN THE GIS-OPS COMMUNITY

Stack Exchange Network

Stack Exchange network consists of 181 Q&A communities including Stack Overflow , the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It only takes a minute to sign up.

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Issues with QgsTask and task manager

I am trying to use the task manager to run a long operation (uploading layer to a GeoServer instance, for the Geoserver Explorer plugin), but I am finding some issues.

Here is the code that I am using:

The issues I have are mainly two:

1) After adding the task to the task manager, it doesnt start. I have to add some call that refreshes the UI, such as logging a dummy message to the QGIS log or calling processEvents() to have it started. I have tried in Win and Mac, and in both cases the task is not triggered. Docs say that the task manager will take care of running it when it can, but that never happens, no matter what I do on the QGIS UI.

2) The finished () method is not always run when the task is finished. The layersUploaded method that is connected to the taskCompleted signal is always run when the task is correctly finished, but the finished method of the task is only called sometimes. That doesn't depend on the success of the task. If it fails, the finished method is only run sometimes, and I could not find any pattern in it.

Any ideas or suggestions?

axel_ande's user avatar

4 Answers 4

QGIS version 3.4.2 If you define a task and add it to the task manager within a function scope, it will cause the task to either not execute properly or, at worst, crash QGIS. Consider the following code.

If you put this in the script editor in QGIS and execute it, it will run just fine. The user can cancel. The exceptions are raised, occasionally. All is well. Now if you replace the last block of the code to be within a function scope, like so:

Now when you run the script you will find that either task1 will appear to run, but the completed() function will never be reached (task2 will NOT run) or QGIS will crash. If you run it twice, QGIS will most surely crash. This will also happen when using the class method, as in OP's code. This is likely a bug and I may link to this answer and report it. A possible workaround would be to take the task creation and execution out of scope, as in my first example, and run it from the script editor.

Update: I have reported this issue to QGIS, however it may not be a bug and just a matter of scope. If you have the following code, in a module named task_example.py, you will find it to work correctly for both the subclassed and fromFunction methods:

You can now, in the python console (or another py file), make the following executions:

Please note that I commented out the parts of the code that cause an exception when the random integer is 42. I was tired of the answer to the ultimate question of life, the universe, and everything throwing exceptions at me.

Subgenius's user avatar

As @Subgenius said, a workaround would be to create the task variable with global scope.

And to call it,

This way, you can call the task from inside a function and a class.

Full code -

Aaditya Ravindran's user avatar

At this time of writing this answer, I can make the task run properly by assigning the task to a python's object attribute.

For example:

In the snippet above, calling the run_task_without_self will run the task badly (no finished or completed signal is emitted). On the second function, run_task_with_self , it will run as expected.

Unfortunately, I don't really understand why, since I just found it somehow the first time, and when I remove the self , it doesn't work anymore. Another thing that I found is if I put the tasks in a dictionary, (e.g. self.task_dict = {'1': QgsTask(...), '2': QgsTask(...)} ), it also doesn't work properly.

ismailsunni's user avatar

Hmm, I've been using QgsTask.fromFunction I've copied in some code that works for me. (Though I cant get Exited by user to work.. that I posted here: My question ).

Your Answer

Sign up or log in, post as a guest.

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service , privacy policy and cookie policy

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

Hot Network Questions

task manager qgis

Your privacy

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy .

task manager qgis

Name already in use

Qgis-documentation / docs / pyqgis_developer_cookbook / tasks.rst.

Tasks - doing heavy work in the background

The code snippets on this page need the following imports if you're outside the pyqgis console:

Introduction

Background processing using threads is a way to maintain a responsive user interface when heavy processing is going on. Tasks can be used to achieve threading in QGIS.

A task ( :class:`QgsTask <qgis.core.QgsTask>` ) is a container for the code to be performed in the background, and the task manager ( :class:`QgsTaskManager <qgis.core.QgsTaskManager>` ) is used to control the running of the tasks. These classes simplify background processing in QGIS by providing mechanisms for signaling, progress reporting and access to the status for background processes. Tasks can be grouped using subtasks.

The global task manager (found with :meth:`QgsApplication.taskManager() <qgis.core.QgsApplication.taskManager>` ) is normally used. This means that your tasks may not be the only tasks that are controlled by the task manager.

There are several ways to create a QGIS task:

Create your own task by extending :class:`QgsTask <qgis.core.QgsTask>`

Create a task from a function

Create a task from a processing algorithm

Any background task (regardless of how it is created) must NEVER use any QObject that lives on the main thread, such as accessing QgsVectorLayer, QgsProject or perform any GUI based operations like creating new widgets or interacting with existing widgets. Qt widgets must only be accessed or modified from the main thread. Data that is used in a task must be copied before the task is started. Attempting to use them from background threads will result in crashes.

Dependencies between tasks can be described using the :meth:`addSubTask() <qgis.core.QgsTask.addSubTask>` function of :class:`QgsTask <qgis.core.QgsTask>` . When a dependency is stated, the task manager will automatically determine how these dependencies will be executed. Wherever possible dependencies will be executed in parallel in order to satisfy them as quickly as possible. If a task on which another task depends is canceled, the dependent task will also be canceled. Circular dependencies can make deadlocks possible, so be careful.

If a task depends on a layer being available, this can be stated using the :meth:`setDependentLayers() <qgis.core.QgsTask.setDependentLayers>` function of :class:`QgsTask <qgis.core.QgsTask>` . If a layer on which a task depends is not available, the task will be canceled.

Once the task has been created it can be scheduled for running using the :meth:`addTask() <qgis.core.QgsTaskManager.addTask>` function of the task manager. Adding a task to the manager automatically transfers ownership of that task to the manager, and the manager will cleanup and delete tasks after they have executed. The scheduling of the tasks is influenced by the task priority, which is set in :meth:`addTask() <qgis.core.QgsTaskManager.addTask>` .

The status of tasks can be monitored using :class:`QgsTask <qgis.core.QgsTask>` and :class:`QgsTaskManager <qgis.core.QgsTaskManager>` signals and functions.

Extending QgsTask

In this example RandomIntegerSumTask extends :class:`QgsTask <qgis.core.QgsTask>` and will generate 100 random integers between 0 and 500 during a specified period of time. If the random number is 42, the task is aborted and an exception is raised. Several instances of RandomIntegerSumTask (with subtasks) are generated and added to the task manager, demonstrating two types of dependencies.

Task from function

Create a task from a function ( doSomething in this example). The first parameter of the function will hold the :class:`QgsTask <qgis.core.QgsTask>` for the function. An important (named) parameter is on_finished , that specifies a function that will be called when the task has completed. The doSomething function in this example has an additional named parameter wait_time .

Task from a processing algorithm

Create a task that uses the algorithm :ref:`qgis:randompointsinextent <qgisrandompointsinextent>` to generate 50000 random points inside a specified extent. The result is added to the project in a safe way.

See also: https://www.opengis.ch/2018/06/22/threads-in-pyqgis3/ .

IMAGES

  1. QGIS task manager prototype v2

    task manager qgis

  2. Using QGIS task manager for background layer saving

    task manager qgis

  3. Workaround for: qgis2web freezes while changing map type

    task manager qgis

  4. QGIS table manager

    task manager qgis

  5. QGIS 3 DB Manager Simple Select SQL

    task manager qgis

  6. Video tutorial QGIS Plugin

    task manager qgis

VIDEO

  1. Lab 5

  2. wmts in QGIS 2 18 vs earlier versions

  3. QGIS table manager

  4. ChatGPT for GIS Operations with PostgreSQL and PostGIS 1

  5. QGIS task manager prototype v2

  6. QGIS Installation

COMMENTS

  1. 15. Tasks

    This means that your tasks may not be the only tasks that are controlled by the task manager. There are several ways to create a QGIS task:.

  2. Task Manager

    Task Manager Plugin icon. (1) votes Loading... Assign feature to a given user. About; Details; Versions. Assign a feature to a given user.

  3. Tasks

    A task ( QgsTask ) is a container for the code to be performed in the background, and the task manager ( QgsTaskManager ) is used to control the running of the

  4. QGIS API Documentation: QgsTaskManager Class Reference

    Detailed Description. Task manager for managing a set of long-running QgsTask tasks. This class can be created directly, or accessed via QgsApplication::

  5. QGIS Task manager demonstation

    Demo of the latest UI for the QGIS task manager.

  6. QGIS task manager prototype v2

    Latest incarnation of the GUI for managing long running tasks in QGIS.

  7. Using QGIS task manager for background layer saving

    Using QGIS task manager for background layer saving. Watch later. Share. Copy link. Info. Shopping. Tap to unmute.

  8. QGIS 3 Plugin Tutorial

    This is where the QGIS background tasks ( QgsTask ) come in very handy. ... We add the task and the task manager makes sure that the task

  9. Issues with QgsTask and task manager

    QGIS version 3.4.2 If you define a task and add it to the task manager within a function scope, it will cause the task to either not execute

  10. QGIS-Documentation/tasks.rst at master

    The global task manager (found with :meth:`QgsApplication.taskManager() <qgis.core.QgsApplication.taskManager>`) is normally used. This means that your tasks