1、作用
在服务中可以知道是哪个其他插件在使用它;
懒汉式使用服务,需要的时候才new;
厂其他插件使用有服务工厂和使用无服务工的服务,没有任何区别,代码都一样;
可根据需要创建多种实现的服务,就是:多种服务对应一个插件。
2、用打印插件举例
提供三种服务,分别是:直接打印、打印后加3个点、加上时间戳打印
3、创建工程PrintServer
①、接口类
absprintserver.h
#ifndef ABSPRINTSERVER_H #define ABSPRINTSERVER_H #include <QObject> class AbsPrintServer { public: virtual ~AbsPrintServer(){} virtual void print(QString) = 0; }; Q_DECLARE_INTERFACE(AbsPrintServer,"judesmorning.zxy.AbsPrintServer") #endif // ABSPRINTSERVER_H
②、直接打印实现类
printserver.h
#ifndef PRINTSERVER_H #define PRINTSERVER_H #include <QObject> #include "absprintserver.h" class PrintServer : public QObject, public AbsPrintServer { Q_OBJECT Q_INTERFACES(AbsPrintServer) public: PrintServer(); void print(QString info) override; }; #endif // PRINTSERVER_H
printserver.cpp
#include "printserver.h" #include <QDebug> PrintServer::PrintServer() { } void PrintServer::print(QString info) { qDebug()<<info+"----print plugin for FirstPlugin"; }
③、打印后加3个点实现类
printserverd.h
#ifndef PRINTSERVERD_H #define PRINTSERVERD_H #include <QObject> #include "absprintserver.h" class PrintServerD : public QObject, public AbsPrintServer { Q_OBJECT Q_INTERFACES(AbsPrintServer) public: PrintServerD(); void print(QString info) override; }; #endif // PRINTSERVERD_H
printserverd.cpp
#include "printserverd.h" #include <QDebug> PrintServerD::PrintServerD() { } void PrintServerD::print(QString info) { qDebug()<<info+"....----print plugin for CreateCtkUiPlugin";; }
④、加上时间戳打印实现类
printservert.h
#ifndef PRINTSERVERT_H #define PRINTSERVERT_H #include <QObject> #include "absprintserver.h" class PrintServerT : public QObject, public AbsPrintServer { Q_OBJECT Q_INTERFACES(AbsPrintServer) public: PrintServerT(); void print(QString info) override; }; #endif // PRINTSERVERT_H
printservert.cpp
#include "printservert.h" #include <QDebug> #include <QTime> PrintServerT::PrintServerT() { } void PrintServerT::print(QString info) { qDebug()<<QTime::currentTime().toString("HH:mm:ss ")<<info+"----print plugin for CreateCtkUiPlugin"; }
⑤、服务工厂类
servicefactory.h
#ifndef SERVICEFACTORY_H #define SERVICEFACTORY_H #include <QObject> #include "printserver.h" #include "printserverd.h" #include "printservert.h" #include "ctkServiceFactory.h" class ServiceFactory : public QObject, public ctkServiceFactory { Q_OBJECT Q_INTERFACES(ctkServiceFactory) public: ServiceFactory(); QObject* getService(QSharedPointer<ctkPlugin> plugin, ctkServiceRegistration registration) override; void ungetService(QSharedPointer<ctkPlugin> plugin, ctkServiceRegistration registration,QObject* service) override; }; #endif // SERVICEFACTORY_H
servicefactory.cpp
#include "servicefactory.h" #include "ctkPlugin.h" #include "ctkPluginConstants.h" #include <QDebug> ServiceFactory::ServiceFactory() { } QObject *ServiceFactory::getService(QSharedPointer<ctkPlugin> plugin, ctkServiceRegistration registration) { Q_UNUSED(registration) QHash<QString,QString> headers = plugin->getHeaders(); ctkVersion version = ctkVersion::parseVersion(headers.value(ctkPluginConstants::PLUGIN_VERSION)); QString name = headers.value(ctkPluginConstants::PLUGIN_NAME); QString symbolicName = headers.value(ctkPluginConstants::PLUGIN_SYMBOLICNAME); Q_UNUSED(version) //暂时没使用到 Q_UNUSED(name) QObject* obj; if(symbolicName == "FirstPlugin") { obj = new PrintServer; } else if(symbolicName == "CreateCtkUiPlugin") { obj = new PrintServerT; } else { obj = new PrintServerD; } return obj; } void ServiceFactory::ungetService(QSharedPointer<ctkPlugin> plugin, ctkServiceRegistration registration, QObject *service) { Q_UNUSED(plugin) Q_UNUSED(registration) Q_UNUSED(service) }
⑥、激活类
activator.h
#ifndef ACTIVATOR_H #define ACTIVATOR_H #include <QObject> #include "ctkPluginActivator.h" #include "ctkPluginContext.h" #include "servicefactory.h" class Activator : public QObject , public ctkPluginActivator { Q_OBJECT Q_INTERFACES(ctkPluginActivator) Q_PLUGIN_METADATA(IID "PrintServer") public: Activator(); void start(ctkPluginContext* context) override; void stop(ctkPluginContext* context) override; private: QScopedPointer<ServiceFactory> factory; }; #endif // ACTIVATOR_H
activator.cpp
#include "activator.h" Activator::Activator() { } void Activator::start(ctkPluginContext *context) { ServiceFactory* s = new ServiceFactory; context->registerService<AbsPrintServer>(s); factory.reset(s); } void Activator::stop(ctkPluginContext *context) { Q_UNUSED(context) }
⑦、工程结构
4、app
main.cpp
#include <QApplication> #include <ctkPluginFrameworkFactory.h> #include <ctkPluginFramework.h> #include <ctkPluginException.h> #include <ctkPluginContext.h> #include <QDebug> #include <QUrl> #include <QDialog> #include <QDir> //ctk头文件 #include "ctkPluginFrameworkLauncher.h" #include "ctkPluginContext.h" #include "ctkPluginException.h" //插件头文件 #include "abslogservice.h" #include "absuiservice.h" #include "signal.h" #include "slot.h" #include "absprintserver.h" QString static logPluginPath = QDir::currentPath()+"/third_libs/plugin/libs/ctk-plugin-first.dll";;//日志插件 QString static uiPluginPath = QDir::currentPath()+"/third_libs/plugin/libs/CreateCtkUiPlugin.dll";//界面框架 QString static signalPluginPath = QDir::currentPath()+"/third_libs/plugin/libs/ctksignalplugin.dll";//signal插件 QString static slotPluginPath = QDir::currentPath()+"/third_libs/plugin/libs/ctkslotplugin.dll";//slot插件 QString static printPluginPath = QDir::currentPath()+"/third_libs/plugin/libs/MPrintServer.dll";//print打印插件 // int main(int argc, char *argv[]) { QApplication a(argc, argv); #if 1 //使用到event框架 QString path = QDir::currentPath() + "/third_libs/ctk/libs"; // 获取插件所在位置 ctkPluginFrameworkLauncher::addSearchPath(path); // 在插件的搜索路径列表中添加一条路径 ctkPluginFrameworkLauncher::start("org.commontk.eventadmin"); ctkPluginContext* context = ctkPluginFrameworkLauncher::getPluginContext(); // 获取插件上下文 // 启动打印插件 try { QSharedPointer<ctkPlugin> plugin = context->installPlugin(QUrl::fromLocalFile(printPluginPath)); plugin->start(ctkPlugin::START_TRANSIENT); qDebug() << "install and start print plugin"; ctkServiceReference reference = context->getServiceReference<AbsPrintServer>(); if (reference) { // 获取指定 ctkServiceReference 引用的服务对象 AbsPrintServer* service = qobject_cast<AbsPrintServer*>(context->getService(reference)); if (service != Q_NULLPTR) { // 调用服务 service->print("running print plugin"); } } } catch (const ctkPluginException &e) { qDebug() << "Failed to start plugin" << e.what(); } // 启动日志插件 try { QSharedPointer<ctkPlugin> plugin = context->installPlugin(QUrl::fromLocalFile(logPluginPath)); plugin->start(ctkPlugin::START_TRANSIENT); qDebug() << "install and start log plugin"; } catch (const ctkPluginException &e) { qDebug() << "Failed to start plugin" << e.what(); } // 启动插件界面插件 try { QSharedPointer<ctkPlugin> plugin = context->installPlugin(QUrl::fromLocalFile(uiPluginPath)); plugin->start(ctkPlugin::START_TRANSIENT); qDebug() << "install and start ui plugin"; } catch (const ctkPluginException &e) { qDebug() << "Failed to start plugin" << e.what(); } // 获取服务引用 ctkServiceReference reference = context->getServiceReference<AbsUiService>(); if (reference) { // 获取指定 ctkServiceReference 引用的服务对象 AbsUiService* service = qobject_cast<AbsUiService*>(context->getService(reference)); if (service != Q_NULLPTR) { // 调用服务 service->init(); } } else { qDebug()<<"reference is null"; } // 停止插件 // ctkPluginFrameworkLauncher::stop(); #endif return a.exec(); }
ps:
主框架【main.cpp】的symbolicName是system.plugin