0、概述
編寫插件主要有3個步驟:接口類、實現類、激活類。根據前面寫的入門插件【https://www.cnblogs.com/judes/p/13220386.html】,總感覺很難理解,為什么還要在實現類的構造函數里注冊服務呢,我們肯定希望把3個步驟的耦合性降低,接口類就只做接口聲明,實現類就只實現接口,激活類就負責將前面的服務整合到ctk框架中。根據這個思路我改了下面這個做法,經過測試沒有問題。
1、核心變化
接口類沒有什么變化,實現類少了注冊的代碼,構造函數也無參數,注冊的過程放在了激活類里
2、接口類
.h
#ifndef ABSSERVICE_H #define ABSSERVICE_H #include <QObject> class AbsService{ public: virtual ~AbsService(){} virtual void exec() = 0; }; Q_DECLARE_INTERFACE(AbsService,"judesmorning.zxy.AbsService") #endif // ABSSERVICE_H
3、實現類
.h
#ifndef IMPSERVICE_H #define IMPSERVICE_H #include <QObject> #include <absservice.h> class ImpService : public QObject, public AbsService { Q_OBJECT Q_INTERFACES(AbsService) public: ImpService(); void exec() override; }; #endif // IMPSERVICE_H
.cpp
#include "impservice.h" #include <QDebug> ImpService::ImpService() { } void ImpService::exec() { qDebug()<<"this is exec imp"; }
4、激活類
.h
#ifndef ACTIVATOR_H #define ACTIVATOR_H #include "ctkPluginContext.h" #include "ctkPluginActivator.h" #include "impservice.h" class Activator : public QObject, public ctkPluginActivator { Q_OBJECT Q_INTERFACES(ctkPluginActivator) Q_PLUGIN_METADATA(IID "TestRequirePlugin") public: Activator(); void start(ctkPluginContext* context) override; void stop(ctkPluginContext* context) override; private: QScopedPointer<AbsService> m_service; }; #endif // ACTIVATOR_H
.cpp
#include "activator.h" #include <QDebug> Activator::Activator() { } void Activator::start(ctkPluginContext *context) { qDebug()<<"start"; ImpService* impService = new ImpService; context->registerService<AbsService>(impService); m_service.reset(impService); } void Activator::stop(ctkPluginContext *context) { qDebug()<<"stop"; Q_UNUSED(context); }
ps:
接口類和實現類都是單純的代碼,跟平時寫的代碼沒有區別;激活類里有一個獨占智能指針,指向接口類【使用多態,指針都指向父類】,然后在start里new一個實現類,注冊這個實現類為服務,功能是實現接口類的接口,然后將智能指針指向這個實現類。可以理解為以后向框架索取這個服務的時候,實際獲取的就是這個new出來的實現類。如果不用智能指針,就需要在stop里手動delete這個實現類。
原理框圖:
更新框圖: