Qgis 开发初级 《Tasks》

Task 是Qgis 封装的多线程,用它可以不卡界面的实现后台的处理逻辑。本章主要用一个封装的例子来演示Task 的使用,同时演示如何用Task 调用Qgis 内部的进度条。

首先我们创建一个接口类

1、Work

IWork.h

#pragma once
#include "QgsFeedback.h"
class IWork
{
public:
	IWork() {};
	virtual ~IWork() {
	};
	virtual bool start() { return true; }; //开始函数

	virtual void end() {};//结束函数

	virtual QgsFeedback* feedback() const { return new QgsFeedback(); };
	virtual void setFeedback(QgsFeedback* feedback) { };
	virtual QString lastError() const { return QString(); };

};

IWork.cpp 是空的

创建一个实现该接口的BaseWork 抽象类,里面QgsFeedback 是和进度条有关的。

BaseWork.h

#pragma once
#include "IWork.h"
#include "QgsFeedback.h"
#include "QObject.h"
class BaseWork:public QObject, public IWork
{
	Q_OBJECT
public:
	BaseWork() = default;
	BaseWork(QString name);
	virtual ~BaseWork() {
	};
	QString name();
	bool start() override; //开始函数

	void end() override;//结束函数

	QgsFeedback* feedback() const override;
	void setFeedback(QgsFeedback* feedback) override;
	QString lastError() const override;

protected:
	QString mName;
	double progress = 0.0;
	double step = 100;
	QgsFeedback* mFeedback;
	QString mLastError;

private:
	
	
	
};

BaseWork.cpp

#include "BaseWork.h"

BaseWork::BaseWork(QString name):mName(name)
{

}

QString BaseWork::name()
{
	return mName;
}

bool BaseWork::start()
{
	return false;
}

void BaseWork::end()
{
}

QgsFeedback* BaseWork::feedback() const { return mFeedback; }

void BaseWork::setFeedback(QgsFeedback* feedback) { mFeedback = feedback; }

QString BaseWork::lastError() const { return mLastError; }

写一个继承该类的具体类,只要继承该类实现具体的接口即可。

2、Task

Qgs 的所有Task 必须继承QgsTask 的类,我们写一个通用类QgsProgressTask。

QgsProgressTask.h

#pragma once
#include <QObject>
#include "qgstaskmanager.h"
#include "qgsfeedback.h"
#include "IWork.h"


class QgsProgressTask : public QgsTask {
    Q_OBJECT

public:
    //构造函数
    QgsProgressTask(IWork * work,QString name="进程");
    QgsProgressTask(QString name);
    ~QgsProgressTask();
    //重写run方法
    bool run() override;
    //重写cancel方法
    void cancel() override;
    //重新结束方法
    void finished(bool result) override;

    //该方法只在没有work的情况下使用
    void complete();

    QgsFeedback* feedback();

signals:
    /**
     * 当任务成功的时候可以发送信号给外部函数做其他处理
     */
    void ZDComplete();

private:
    IWork* mWork = nullptr;

    //该属性只在没有work的情况下使用
    bool miscomplete = false;
    //回调
    std::unique_ptr< QgsFeedback >mOwnedFeedback;
};

QgsProgressTask.cpp

#include "QgsProgressTask.h"
QgsProgressTask::QgsProgressTask(IWork* work,QString name ): QgsTask(name, QgsTask::CanCancel), mWork(work), mOwnedFeedback(new QgsFeedback())
{
	work->setFeedback(mOwnedFeedback.get());
}
QgsProgressTask::QgsProgressTask(QString name): QgsTask(name, QgsTask::CanCancel),  mOwnedFeedback(new QgsFeedback())
{
}
QgsProgressTask::~QgsProgressTask()
{
}

bool QgsProgressTask::run()
{
	connect(mOwnedFeedback.get(), &QgsFeedback::progressChanged, this, &QgsProgressTask::setProgress);
	connect(mOwnedFeedback.get(), &QgsFeedback::canceled, this, &QgsProgressTask::cancel);
	if(mWork!=nullptr)
		mWork->start();
	else {
		while (!miscomplete) {
			int i=0;
		}
	}
	return true;
}

void QgsProgressTask::cancel()
{
	mOwnedFeedback->cancel();
	QgsTask::cancel();
	
}

void QgsProgressTask::finished(bool result)
{
	Q_UNUSED(result)
		emit ZDComplete();

	if (mWork != nullptr) {
		mWork->end();
		delete mWork;
		mWork = nullptr;
	}
	
}

void QgsProgressTask::complete()
{
	miscomplete = true;
}

QgsFeedback* QgsProgressTask::feedback()
{
	return mOwnedFeedback.get();
}

3、Task的使用

假设一个Work 继承自BaseWork,就可以用下面代码运行Task。Task一旦用taskManager 加入就开始运行了。

//开始任务
	Work* mwork = new Work(mName);
	QgsProgressTask* mtask = new QgsProgressTask(mwork, mName);
	QObject::connect(mtask, SIGNAL(ZDComplete()), this, SLOT(end()));
	QgsApplication::taskManager()->addTask(mtask);

4、进度条

可以用下面代码去设置进度条

    mFeedback->setProgress(add);
    //取消任务的回调
    if (mFeedback->isCanceled())
    {
             
    }

5、小节

本章主要介绍了Task 的使用和进度条的设置。QgisTask 的本质是开启一个线程,其实可以用其他的多线程的方式代替,但是QgisTask 可以与qgis 自己的界面有更好 的衔接,更方便的调用qgis的界面。

上一篇:笔记整理—linux驱动开发部分(2)模块信息与编译


下一篇:RSocket vs WebSocket:Spring Boot 3.3 中的两大实时通信利器