CTK-服务工厂的使用

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

posted @ 2020-07-05 04:02  朱小勇  阅读(902)  评论(1编辑  收藏  举报