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这个实现类。
原理框图:
更新框图: