QGIS/python/core/qgstaskmanager.sip
2017-03-25 16:23:29 +10:00

359 lines
12 KiB
Plaintext

/**
* \ingroup core
* \class QgsTask
* \brief Abstract base class for long running background tasks. Tasks can be controlled directly,
* or added to a QgsTaskManager for automatic management.
*
* Derived classes should implement the process they want to execute in the background
* within the run() method. This method will be called when the
* task commences (ie via calling start() ).
*
* Long running tasks should periodically check the isCanceled() flag to detect if the task
* has been canceled via some external event. If this flag is true then the task should
* clean up and terminate at the earliest possible convenience.
*
* \note Added in version 3.0
*/
class QgsTask : QObject
{
%TypeHeaderCode
#include <qgstaskmanager.h>
%End
public:
//! Status of tasks
enum TaskStatus
{
Queued, /*!< Task is queued and has not begun */
OnHold, /*!< Task is queued but on hold and will not be started */
Running, /*!< Task is currently running */
Complete, /*!< Task successfully completed */
Terminated, /*!< Task was terminated or errored */
};
//! Task flags
enum Flag
{
CanCancel, //!< Task can be canceled
AllFlags, //!< Task supports all flags
};
typedef QFlags<QgsTask::Flag> Flags;
/**
* Constructor for QgsTask.
* @param description text description of task
* @param flags task flags
*/
QgsTask( const QString& description = QString(), const Flags& flags = AllFlags );
/**
* Returns the flags associated with the task.
*/
Flags flags() const;
/**
* Returns true if the task can be canceled.
*/
bool canCancel() const;
/**
* Returns true if the task is active, ie it is not complete and has
* not been canceled.
*/
bool isActive() const;
/**
* Returns the current task status.
*/
TaskStatus status() const;
/**
* Returns the task's description.
*/
QString description() const;
/**
* Returns the task's progress (between 0.0 and 100.0)
*/
double progress() const;
virtual void cancel();
/**
* Places the task on hold. If the task in not queued
* (ie it is already running or has finished) then calling this has no effect.
* Calling this method only has an effect for tasks which are managed
* by a QgsTaskManager.
* @see unhold()
*/
void hold();
/**
* Releases the task from being held. For tasks managed by a QgsTaskManager
* calling this will re-add them to the queue. If the
* task in not currently being held then calling this has no effect.
* @see hold()
*/
void unhold();
//! Controls how subtasks relate to their parent task
enum SubTaskDependency
{
SubTaskIndependent, //!< Subtask is independent of the parent, and can run before, after or at the same time as the parent.
ParentDependsOnSubTask, //!< Subtask must complete before parent can begin
};
/**
* Adds a subtask to this task.
*
* Subtasks allow a single task to be created which
* consists of multiple smaller tasks. Subtasks are not visible or indepedently
* controllable by users. Ownership of the subtask is transferred.
* Subtasks can have an optional list of dependent tasks, which must be completed
* before the subtask can begin. By default subtasks are considered independent
* of the parent task, ie they can be run either before, after, or at the same
* time as the parent task. This behavior can be overridden through the subTaskDependency
* argument.
*
* The parent task must be added to a QgsTaskManager for subtasks to be utilized.
* Subtasks should not be added manually to a QgsTaskManager, rather, only the parent
* task should be added to the manager.
*
* Subtasks can be nested, ie a subtask can legally be a parent task itself with
* its own set of subtasks.
*/
void addSubTask( QgsTask* subTask /Transfer/, const QgsTaskList& dependencies = QgsTaskList(),
SubTaskDependency subTaskDependency = SubTaskIndependent );
void setDependentLayers( const QList<QgsMapLayer*>& dependentLayers );
QList< QgsMapLayer* > dependentLayers() const;
signals:
/**
* Will be emitted by task when its progress changes.
* @param progress percent of progress, from 0.0 - 100.0
* @note derived classes should not emit this signal directly, instead they should call
* setProgress()
*/
void progressChanged( double progress );
/**
* Will be emitted by task when its status changes.
* @param status new task status
* @note derived classes should not emit this signal directly, it will automatically
* be emitted
*/
void statusChanged( int status );
/**
* Will be emitted by task to indicate its commencement.
* @note derived classes should not emit this signal directly, it will automatically
* be emitted when the task begins
*/
void begun();
/**
* Will be emitted by task to indicate its successful completion.
* @note derived classes should not emit this signal directly, it will automatically
* be emitted
*/
void taskCompleted();
/**
* Will be emitted by task if it has terminated for any reason
* other then completion (e.g., when a task has been canceled or encountered
* an internal error).
* @note derived classes should not emit this signal directly, it will automatically
* be emitted
*/
void taskTerminated();
protected:
/**
* Performs the task's operation. This method will be called when the task commences
* (ie via calling start() ), and subclasses should implement the operation they
* wish to perform in the background within this method.
*
* A task must return a boolean value to indicate whether the
* task was completed successfully or terminated before completion.
*/
virtual bool run() = 0;
/**
* If the task is managed by a QgsTaskManager, this will be called after the
* task has finished (whether through successful completion or via early
* termination). The result argument reflects whether
* the task was successfully completed or not. This method is always called
* from the main thread, so it is safe to create widgets and perform other
* operations which require the main thread. However, the GUI will be blocked
* for the duration of this method so tasks should avoid performing any
* lengthy operations here.
*/
virtual void finished( bool result );
/**
* Will return true if task should terminate ASAP. If the task reports the CanCancel
* flag, then derived classes' run() methods should periodically check this and
* terminate in a safe manner.
*/
bool isCanceled() const;
protected slots:
/**
* Sets the task's current progress. If task reports the CanReportProgress flag then
* the derived class should call this method whenever the task wants to update its
* progress. Calling will automatically emit the progressChanged signal.
* @param progress percent of progress, from 0.0 - 100.0
*/
void setProgress( double progress );
};
QFlags<QgsTask::Flag> operator|(QgsTask::Flag f1, QFlags<QgsTask::Flag> f2);
//! List of QgsTask objects
typedef QList< QgsTask* > QgsTaskList;
/** \ingroup core
* \class QgsTaskManager
* \brief Task manager for managing a set of long-running QgsTask tasks. This class can be created directly,
* or accessed via a global instance.
* \note Added in version 2.16
*/
class QgsTaskManager : QObject
{
%TypeHeaderCode
#include <qgstaskmanager.h>
%End
public:
/** Constructor for QgsTaskManager.
* @param parent parent QObject
*/
QgsTaskManager( QObject* parent /TransferThis/ = nullptr );
virtual ~QgsTaskManager();
/**
* Definition of a task for inclusion within a task bundle.
*/
struct TaskDefinition
{
/**
* Constructor for TaskDefinition. Ownership of the task is transferred to the definition.
*/
explicit TaskDefinition( QgsTask* task, QgsTaskList dependentTasks = QgsTaskList() );
//! Task
QgsTask* task;
/**
* List of dependencies which must be completed before task can run. If any dependent tasks are
* canceled this task will also be canceled. Dependent tasks must also be added
* to the task manager for proper handling of dependencies.
*/
QgsTaskList dependentTasks;
};
/** Adds a task to the manager. 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.
* @returns unique task ID
*/
long addTask( QgsTask* task /Transfer/, int priority = 0 );
/**
* 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.
* @returns unique task ID
*/
long addTask( const TaskDefinition& task /Transfer/, int priority = 0 );
/** Returns the task with matching ID.
* @param id task ID
* @returns task if found, or nullptr
*/
QgsTask* task( long id ) const;
/** Returns all tasks tracked by the manager.
*/
QList<QgsTask*> tasks() const;
//! Returns the number of tasks tracked by the manager.
int count() const;
/** Returns the unique task ID corresponding to a task managed by the class.
* @param task task to find
* @returns task ID, or -1 if task not found
*/
long taskId( QgsTask* task ) const;
//! Instructs all tasks tracked by the manager to terminate.
void cancelAll();
//! Returns true if all dependencies for the specified task are satisfied
bool dependenciesSatisfied( long taskId ) const;
//! Returns the set of task IDs on which a task is dependent
//! @note not available in Python bindings
//QSet< long > dependencies( long taskId ) const;
QList< QgsMapLayer* > dependentLayers( long taskId ) const;
QList< QgsTask* > tasksDependentOnLayer( QgsMapLayer* layer ) const;
/** Returns a list of the active (queued or running) tasks.
* @see countActiveTasks()
*/
QList< QgsTask* > activeTasks() const;
/** Returns the number of active (queued or running) tasks.
* @see activeTasks()
* @see countActiveTasksChanged()
*/
int countActiveTasks() const;
signals:
//! Will be emitted when a task reports a progress change
//! @param taskId ID of task
//! @param progress percent of progress, from 0.0 - 100.0
void progressChanged( long taskId, double progress );
//! Will be emitted when only a single task remains to complete
//! and that task has reported a progress change
//! @param progress percent of progress, from 0.0 - 100.0
void finalTaskProgressChanged( double progress );
//! Will be emitted when a task reports a status change
//! @param taskId ID of task
//! @param status new task status
void statusChanged( long taskId, int status );
//! Emitted when a new task has been added to the manager
//! @param taskId ID of task
void taskAdded( long taskId );
//! Emitted when a task is about to be deleted
//! @param taskId ID of task
void taskAboutToBeDeleted( long taskId );
//! Emitted when all tasks are complete
//! @see countActiveTasksChanged()
void allTasksFinished();
//! Emitted when the number of active tasks changes
//! @see countActiveTasks()
void countActiveTasksChanged( int count );
};