CTK-使用ctk框架完成日志、打印、界面插件


 一、項目介紹

1、主要為了在此小型測試項目中用到幾乎所有ctk的常用知識:

插件間通信、服務工廠、服務追蹤、事件監聽、框架封裝

2、項目共包含3個插件
日志插件:用於模擬將接收的信息存儲到日志中【這里只做簡單的打印】,並且能夠接收信息【主要來自界面插件】

打印插件:根據不同的插件返回提供不同打印服務

界面插件:封裝一個界面插件,能夠向框架發送信息【類方式和信號槽方式】

3、架構圖

 

 

 二、打印插件編寫

1、工程結構

 

2、接口類

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

3、實現類1,為日志插件提供服務

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";
}

4、實現類2,為界面插件提供服務

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";
}

5、實現類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 unknown plugin";;
}

6、單獨為接口編寫服務追蹤類

tracker.h

#ifndef TRACKER_H
#define TRACKER_H

#include "ctkServiceTracker.h"
#include "absprintserver.h"
#include "ctkPluginContext.h"
class Tracker : public ctkServiceTracker<AbsPrintServer*>
{
public:
    Tracker(ctkPluginContext* context);
protected:
    AbsPrintServer* addingService(const ctkServiceReference& reference) override;
    void modifiedService(const ctkServiceReference& reference, AbsPrintServer* service) override;
    void removedService(const ctkServiceReference& reference, AbsPrintServer* service) override;
private:
    ctkPluginContext* context;
};

#endif // TRACKER_H

tracker.cpp

#include "tracker.h"


Tracker::Tracker(ctkPluginContext *context)
    : ctkServiceTracker<AbsPrintServer*> (context)
{

}

AbsPrintServer *Tracker::addingService(const ctkServiceReference &reference)
{
    AbsPrintServer* service = static_cast<AbsPrintServer*>(ctkServiceTracker::addingService(reference));
    return service;
}

void Tracker::modifiedService(const ctkServiceReference &reference, AbsPrintServer* service)
{
    ctkServiceTracker::modifiedService(reference,service);
}

void Tracker::removedService(const ctkServiceReference &reference, AbsPrintServer* service)
{
    ctkServiceTracker::removedService(reference,service);
}

注意這個服務追蹤類是在日志插件里使用的,只是從職責上來講這個類應該編寫此插件的人來編寫,降低耦合性

 

三、日志插件編寫

1、工程結構

2、接口類

abslogservice.h

#ifndef ABSLOGSERVICE_H
#define ABSLOGSERVICE_H

#include <QObject>
class AbsLogService{
public:
    virtual ~AbsLogService(){}
    virtual void log(QString info) = 0;
};
Q_DECLARE_INTERFACE(AbsLogService,"judesmorning.zxy.AbsLogService")


#endif // ABSLOGSERVICE_H

3、實現類

logservice.h

#ifndef LOGSERVICE_H
#define LOGSERVICE_H
#include <QObject>
#include "includes.h"
#include "abslogservice.h"
#include "service/event/ctkEventHandler.h"
#include "ctkPluginFrameworkEvent.h"
#include "ctkPluginEvent.h"
#include "ctkServiceEvent.h"
#include "tracker.h"

class ctkPluginContext;
class LogService : public QObject, public AbsLogService, public ctkEventHandler
{
    Q_OBJECT
    Q_INTERFACES(AbsLogService)
    Q_INTERFACES(ctkEventHandler)
public:
    LogService(ctkPluginContext* context);
    void log(QString info) override;
    void handleEvent(const ctkEvent& event) override;
private slots:
    // 監聽框架事件
    void onFrameworkEvent(const ctkPluginFrameworkEvent& event);
    // 監聽插件事件
    void onPluginEvent(const ctkPluginEvent& event);
    // 監聽服務事件
    void onServiceEvent(const ctkServiceEvent& event);
private:
    QString getLevelStr(const _Log_Level& level) const;//獲取日志類型字符串
    void print(QString info);//使用打印插件打印東西
private:
    ctkPluginContext* context;
    QScopedPointer<Tracker> p_tracker;
};

#endif // LOGSERVICE_H

logservice.cpp

#include "logservice.h"
#include <QTime>
#include <QDebug>
#include "ctkPluginContext.h"
#include "absprintserver.h"
#include "ctkServiceTracker.h"

LogService::LogService(ctkPluginContext* context)
    :context(context)
{
#if 1 //通過服務追蹤方式獲取打印插件
    p_tracker.reset(new Tracker(context));
    p_tracker->open();
//    AbsPrintServer* printService = static_cast<AbsPrintServer*>(p_tracker->getService());
//    printService->print("use tracker to get print plugin--------log plugin");
#endif

#if 1 //監聽ctk事件
    context->connectFrameworkListener(this, SLOT(onFrameworkEvent(ctkPluginFrameworkEvent)));
    context->connectPluginListener(this, SLOT(onPluginEvent(ctkPluginEvent)));
    //QString filter = QString("(%1=%2)").arg(ctkPluginConstants::OBJECTCLASS).arg("org.commontk.eventadmin");// 過濾 ctkEventAdmin 服務
    //context->connectServiceListener(this,SLOT(onServiceEvent(ctkServiceEvent))); //, filter);
    context->connectServiceListener(this,"onServiceEvent"); //, filter);
#endif
}

void LogService::log(QString info)
{
    qDebug()<<"log plugin save a log--->"+QTime::currentTime().toString("HH:mm:ss    ") + info;
}

void LogService::handleEvent(const ctkEvent &event)
{
    qDebug()<<"log plugin rcv a event----------log plugin";
    _Log_Level level =  static_cast<_Log_Level>(event.getProperty("level").toInt());
    QString pluginName = event.getProperty("pluginName").toString();
    QString info = event.getProperty("info").toString();
    QString rcvLogInfo = QString("%1   %2   %3.")
            .arg(getLevelStr(level))
            .arg(pluginName)
            .arg(info);
    log(rcvLogInfo);
}

QString LogService::getLevelStr(const _Log_Level &level) const
{
    QString ret;
    switch (static_cast<int>(level))
    {
    case LOG_LEVEL_DEBUG:
        ret = "DEBUG";
        break;
    case LOG_LEVEL_INFO:
        ret = "INFO";
        break;
    case LOG_LEVEL_WARNING:
        ret = "WARNING";
        break;
    case LOG_LEVEL_ERROR:
        ret = "ERROR";
        break;
    case LOG_LEVEL_CRITICAL:
        ret = "CRITICAL";
        break;
    default:
        ret = "UKNOWN";
        break;
    }
    return ret;
}

void LogService::print(QString info)
{
#if 0 //直接向ctk框架索要服務
    ctkServiceReference reference = context->getServiceReference<AbsPrintServer>();
    if (reference)
    {
        // 獲取指定 ctkServiceReference 引用的服務對象
        AbsPrintServer* service = qobject_cast<AbsPrintServer*>(context->getService(reference));
        if (service != Q_NULLPTR)
        {
            // 調用服務
            service->print(info);
        }
    }
#endif

#if 1 //通過tracker向ctk索要服務
    AbsPrintServer* service = static_cast<AbsPrintServer*>(p_tracker->getService());
    if (service != Q_NULLPTR)
    {
        service->print("log plugin with tracker:"+info);
    }
    else
    {
        qDebug()<<"get AbsPrintServer from tracker failed";
    }
#endif
}

void LogService::onFrameworkEvent(const ctkPluginFrameworkEvent &event)
{
    if (!event.isNull())
    {
        QSharedPointer<ctkPlugin> plugin = event.getPlugin();
        qDebug() << "FrameworkEvent: [" << plugin->getSymbolicName() << "]" << event.getType() << event.getErrorString();
    }
    else
    {
        qDebug() << "The framework event is null";
    }
}

void LogService::onPluginEvent(const ctkPluginEvent &event)
{
    if (!event.isNull())
    {
        QSharedPointer<ctkPlugin> plugin = event.getPlugin();
        qDebug() << "PluginEvent: [" << plugin->getSymbolicName() << "]" << event.getType();
    }
    else
    {
        qDebug() << "The plugin event is null";
    }
}

void LogService::onServiceEvent(const ctkServiceEvent &event)
{
    if (!event.isNull())
    {
        ctkServiceReference ref = event.getServiceReference();
        QSharedPointer<ctkPlugin> plugin = ref.getPlugin();
        qDebug() << "ServiceEvent: [" << plugin->getSymbolicName() << "]" << event.getType() << ref.getUsingPlugins();
    }
    else
    {
        qDebug() << "The service event is null";
    }
}

4、激活類

firstpluginactivator.h

#ifndef FIRSTPLUGINACTIVATOR_H
#define FIRSTPLUGINACTIVATOR_H


#include <QObject>
#include "ctkPluginActivator.h"
#include "ctkPluginContext.h"
#include "logservice.h"
class FirstPluginActivator : public QObject, public ctkPluginActivator
{
    Q_OBJECT
    Q_INTERFACES(ctkPluginActivator)
    Q_PLUGIN_METADATA(IID "LogPlugin")

public:
    FirstPluginActivator();
    void start(ctkPluginContext *context);
    void stop(ctkPluginContext *context);
private:
    QScopedPointer<AbsLogService> m_log;
};

#endif // FIRSTPLUGINACTIVATOR_H

firstpluginactivator.cpp

#include "firstpluginactivator.h"
#include <QDebug>
#include "service/event/ctkEventHandler.h"
#include "service/event/ctkEventConstants.h"
#include "absprintserver.h"
FirstPluginActivator::FirstPluginActivator()
{

}

//注冊插件並訂閱事件
void FirstPluginActivator::start(ctkPluginContext *context)
{
//    qDebug() << "FirstPluginActivator start";
    LogService* service = new LogService(context);
    m_log.reset(service);
    ctkDictionary props;
    props[ctkEventConstants::EVENT_TOPIC] = "kdhy/yunwei/generalevent/log";
    props[ctkEventConstants::EVENT_FILTER] = "(pluginName=CreateCtkUiPlugin)";
    context->registerService<ctkEventHandler>(service, props);
    context->registerService<AbsLogService>(service);
}

void FirstPluginActivator::stop(ctkPluginContext *context)
{
    Q_UNUSED(context)
}

5、插件間通信的結構體定義

includes.h

#ifndef INCLUDES_H
#define INCLUDES_H

#include <QString>
/*公共定義*/

//日志相關
enum _Log_Level{
    LOG_LEVEL_DEBUG = 0,
    LOG_LEVEL_INFO,
    LOG_LEVEL_WARNING,
    LOG_LEVEL_ERROR,
    LOG_LEVEL_CRITICAL
};//日志等級
typedef struct _LogInfo {
    _Log_Level level;   //日志類型
    QString pluginName; //插件名稱
    QString info;       //日志信息
} LogInfo;//日志詳情


#endif // INCLUDES_H

 

四、界面類

1、工程結構

 

2、接口類

absuiservice.h

#ifndef ABSUISERVICE_H
#define ABSUISERVICE_H
#include <QObject>
class AbsUiService{
public:
    virtual ~AbsUiService(){}
    virtual void init() = 0;
};
Q_DECLARE_INTERFACE(AbsUiService,"judesmorning.zxy.AbsUiService")


#endif // ABSUISERVICE_H

 

3、實現類

uiservice.h

#ifndef UISERVICE_H
#define UISERVICE_H

#include <QObject>
#include "absuiservice.h"
#include "includes.h"
#include "myui.h"

class ctkPluginContext;
class UiService : public QObject, public AbsUiService
{
    Q_OBJECT
    Q_INTERFACES(AbsUiService)
public:
    UiService(ctkPluginContext* context);
    void init() override;
private slots:
    void publishLogEventSlot(LogInfo logInfo);
private:
    ctkPluginContext* context;//ctk上下文對象
    Myui myui;//界面對象
};

#endif // UISERVICE_H

uiservice.cpp

#include "uiservice.h"
#include "ctkPluginContext.h"
#include "service/event/ctkEventAdmin.h"
#include <QDebug>
#include <QDialog>

UiService::UiService(ctkPluginContext* context)
    :context(context)
{
    context->registerService<AbsUiService>(this);
    QObject::connect(&myui,SIGNAL(publishLogEventSignal(LogInfo)),this,SLOT(publishLogEventSlot(LogInfo)));

    //發送日志事件到ctk框架,signal方式
    ctkServiceReference ref = context->getServiceReference<ctkEventAdmin>();
    if (ref)
    {
        ctkEventAdmin* eventAdmin = context->getService<ctkEventAdmin>(ref);
        eventAdmin->publishSignal(&myui,SIGNAL(publishLogSignal(ctkDictionary)),"kdhy/yunwei/generalevent/log",Qt::QueuedConnection);
    }
}


void UiService::init()
{
    myui.show();
}

//發送日志事件到ctk框架,event方式
void UiService::publishLogEventSlot(LogInfo logInfo)
{
    ctkServiceReference ref = context->getServiceReference<ctkEventAdmin>();
    if (ref) {
        ctkEventAdmin* eventAdmin = context->getService<ctkEventAdmin>(ref);
        ctkDictionary props;
        props["level"] = logInfo.level;
        props["pluginName"] = logInfo.pluginName;
        props["info"] = logInfo.info;
        ctkEvent event("kdhy/yunwei/generalevent/log", props);
        qDebug() << "ui plugin send " << logInfo.info;
        eventAdmin->sendEvent(event);//sendEvent:同步 postEvent:異步
    }
}

4、主顯示界面

myui.h

#ifndef MYUI_H
#define MYUI_H

#include <QWidget>
#include "includes.h"
#include "service/event/ctkEventAdmin.h"
namespace Ui {
class Myui;
}

class Myui : public QWidget
{
    Q_OBJECT

public:
    explicit Myui(QWidget *parent = nullptr);
    ~Myui();

signals:
void publishLogEventSignal(LogInfo);
void publishLogSignal(ctkDictionary info);

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

private:
    Ui::Myui *ui;
};

#endif // MYUI_H

myui.cpp

#include "myui.h"
#include "ui_myui.h"

Myui::Myui(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Myui)
{
    ui->setupUi(this);
}

Myui::~Myui()
{
    delete ui;
}

//發送event事件
void Myui::on_pushButton_clicked()
{
    qDebug()<<"ui plugin send a event";
    LogInfo logInfo;
    logInfo.level = LOG_LEVEL_INFO;
    logInfo.pluginName = "CreateCtkUiPlugin";
    logInfo.info = "Event info:"+ui->textEdit->toPlainText();
    emit publishLogEventSignal(logInfo);
}
//發送信號事件
void Myui::on_pushButton_2_clicked()
{
    ctkDictionary props;
    props["level"] = LOG_LEVEL_INFO;;
    props["pluginName"] = "CreateCtkUiPlugin";
    props["info"] = "Signal info:"+ui->textEdit->toPlainText();
    emit publishLogSignal(props);
}

myui.ui

 

 

5、激活類

uiactivator.h

#ifndef UIACTIVATOR_H
#define UIACTIVATOR_H

#include <QObject>
#include "ctkPluginActivator.h"
#include "ctkPluginContext.h"
#include "uiservice.h"

class UiActivator: public QObject, public ctkPluginActivator
{
    Q_OBJECT
    Q_INTERFACES(ctkPluginActivator)
    Q_PLUGIN_METADATA(IID "UiPlugin")
public:
    UiActivator();
    void start(ctkPluginContext *context);
    void stop(ctkPluginContext *context);
private:
    QScopedPointer<AbsUiService> m_ui;
};

#endif // UIACTIVATOR_H

uiactivator.cpp

#include "uiactivator.h"
#include <QtDebug>
UiActivator::UiActivator()
{

}
void UiActivator::start(ctkPluginContext *context)
{
//    qDebug() << "ui plugin start";
    m_ui.reset(new UiService(context));
}

void UiActivator::stop(ctkPluginContext *context)
{
    Q_UNUSED(context)
}

6、插件間通信的結構體定義

includes.h

#ifndef INCLUDES_H
#define INCLUDES_H

#include <QString>
/*公共定義*/

//日志相關
enum _Log_Level{
    LOG_LEVEL_DEBUG = 0,
    LOG_LEVEL_INFO,
    LOG_LEVEL_WARNING,
    LOG_LEVEL_ERROR,
    LOG_LEVEL_CRITICAL
};//日志等級
typedef struct _LogInfo {
    _Log_Level level;   //日志類型
    QString pluginName; //插件名稱
    QString info;       //日志信息
} LogInfo;//日志詳情


#endif // INCLUDES_H

 

五、使用

1、新建控制台工程

 

 由於用到了界面,所以這個工程不能是無界面的

2、.pro

#-------------------------------------------------
#
# Project created by QtCreator 2020-07-02T18:12:37
#
#-------------------------------------------------

#QT       += core
QT += gui widgets
CONFIG += console c++11
CONFIG -= app_bundle

TARGET = CtkFramework
#TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0


SOURCES += \
        main.cpp \
    pullservice.cpp



# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target



# CTK源碼路徑
INCLUDEPATH += $$PWD/third_libs/ctk/include/CTK_src/Core \
            += $$PWD/third_libs/ctk/include/CTK_src/PluginFramework
# CTK安裝路徑
INCLUDEPATH += $$PWD/third_libs/ctk/include/CTK_install/Core \
            += $$PWD/third_libs/ctk/include/CTK_install/PluginFramework
# CTK庫路徑
LIBS += -L$$PWD/third_libs/ctk/libs -lCTKCore -lCTKPluginFramework


# 插件頭文件路徑
INCLUDEPATH += $$PWD/third_libs/plugin/include

HEADERS += \
    pullservice.h

3、框架封裝類

pullservice.h

#ifndef PULLSERVICE_H
#define PULLSERVICE_H

#include <QDebug>
#include <mutex>
#include <QDir>
#include <QTime>

#include "ctkPluginFrameworkLauncher.h"
#include "ctkPluginContext.h"
#include "ctkPluginException.h"
#include "ctkPluginFrameworkFactory.h"
#include "ctkPluginFramework.h"
#include "ctkPluginException.h"
#include "ctkPluginContext.h"

namespace  PULLSERVICE{
#define PRINTF_LOCATION() qDebug()<<"ret in:" << __FILE__ << " at:"<<__LINE__
#define RET_VALUE_IF_NOT_EAQU(a,b,c)  \
    do {  \
    if(a!=b) \
{        \
    PRINTF_LOCATION();\
    return c; \
    }        \
    } while (false)
#define RET_VALUE_IF_EAQU(a,b,c)  \
    do {  \
    if(a==b) \
{        \
    PRINTF_LOCATION();\
    return c; \
    }        \
    } while (false)
#define RET_IF_NOT_EAQU(a,b)  \
    do {  \
    if(a!=b) \
{        \
    PRINTF_LOCATION();\
    return; \
    }        \
    } while (false)
#define RET_IF_EAQU(a,b)  \
    do {  \
    if(a==b) \
{        \
    PRINTF_LOCATION();\
    return; \
    }        \
    } while (false)
}

using namespace PULLSERVICE;
class AbsUiService;
class AbsLogService;
class PullService
{
protected:
    virtual ~PullService();
private:
    PullService();
//    PullService(const PullService&) = delete;
//    PullService& operator=(const PullService&) = delete;
    void print(QString info);
public:
    static PullService* getInstance();
    //對外接口
    void initCtkFramework(bool usingEventAdmin = false);//初始化框架
    void initServices();//初始化所有服務
    template<class T>//獲取服務,通過模板
    T* getService()
    {
        T* s = nullptr;
        RET_VALUE_IF_EAQU(context,nullptr,s);
        ctkServiceReference reference = context->getServiceReference<T>();
        if(reference)
        {
            s = context->getService<T>(reference);// 獲取指定 ctkServiceReference 引用的服務對象
            if (s == nullptr)
            {
                print("Try to get a invalid service");
            }
        }
        return s;
    }
    void stopFramework();//關閉ctk框架
private:
    static PullService* instance;
    static std::mutex mMutex;
    volatile bool usingEventAdmin = false;
private:
    QStringList pluginNames;//所有插件名字
    //ctk相關的變量
    ctkPluginFrameworkFactory frameworkFactory;
    ctkPluginContext* context = nullptr;
private:
    Q_DISABLE_COPY(PullService)
};

#endif // PULLSERVICE_H

pullservice.cpp

 

#include "pullservice.h"
//插件頭文件
#include "abslogservice.h"
#include "absuiservice.h"
#include "signal.h"
#include "slot.h"
#include "absprintserver.h"
#include "abslogtracker.h"

PullService* PullService::instance = nullptr;
std::mutex PullService::mMutex;

PullService::PullService()
{
    print("PullService construct");
    pluginNames << "MPrintServer.dll"
                << "ctk-plugin-first.dll"
                << "CreateCtkUiPlugin.dll"
                   //                << "ctksignalplugin.dll"
                   //                << "ctkslotplugin.dll"
                << "ctkplugintracker.dll"
                   ;
}
PullService::~PullService()
{
    print("PullService destruct");
}

PullService* PullService::getInstance()
{
    if(nullptr == instance)
    {
        mMutex.lock();
        if(nullptr == instance)
        {
            instance = new PullService;
        }
        mMutex.unlock();
    }
    return instance;
}

/*****************************************************************/
//作者:朱小勇
//函數名稱:初始化ctk框架
//函數參數:usingEventAdmin是否使用eventadmin
//函數返回值:NULL
//函數作用:NULL
//備注:NULL
/*****************************************************************/
void PullService::initCtkFramework(bool usingEventAdmin)
{
    if(nullptr != context)
    {
        print("ctkPluginContext is not null at first time,maybe you have call this method.Try restart app to resolve this problem");
        return;
    }
    this->usingEventAdmin = usingEventAdmin;
    if(usingEventAdmin)
    {
        QString path = QDir::currentPath() + "/third_libs/ctk/libs";    // 獲取插件所在位置
        ctkPluginFrameworkLauncher::addSearchPath(path);    // 在插件的搜索路徑列表中添加一條路徑
        ctkPluginFrameworkLauncher::start("org.commontk.eventadmin");
        context = ctkPluginFrameworkLauncher::getPluginContext();
    }
    else
    {
        QSharedPointer<ctkPluginFramework> framework = frameworkFactory.getFramework();
        // 初始化並啟動插件框架
        try {
            framework->init();
            framework->start();
            context = framework->getPluginContext();
        } catch (const ctkPluginException &e) {
            this->print("CTK plugin framework init failed:"+QString(e.what()));
        }
    }
}

/*****************************************************************/
//作者:朱小勇
//函數名稱:初始化服務
//函數參數:NULL
//函數返回值:NULL
//函數作用:NULL
//備注:安裝啟動插件
/*****************************************************************/
void PullService::initServices()
{
    RET_IF_EAQU(context,nullptr);
    QString prefixFilePath = QDir::currentPath()+"/third_libs/plugin/libs/";
    QString path;
    foreach (QString oneFileName , pluginNames)
    {
        path = prefixFilePath+oneFileName;
        try {
            // 安裝插件
            print(QString("Ready to init plugin:%1").arg(oneFileName));
            QSharedPointer<ctkPlugin> plugin = context->installPlugin(QUrl::fromLocalFile(path));
            print(QString("Plugin[%1_%2] installed...").arg(plugin->getSymbolicName()).arg(plugin->getVersion().toString()));
            // 啟動插件
            plugin->start(ctkPlugin::START_TRANSIENT);
            print(QString("Plugin[%1_%2] started...").arg(plugin->getSymbolicName()).arg(plugin->getVersion().toString()));
        } catch (const ctkPluginException &e) {
            print(QString("Failed install or start plugin:%1").arg(e.what()));
        }
    }
}

/*****************************************************************/
//作者:朱小勇
//函數名稱:停止框架
//函數參數:NULL
//函數返回值:NULL
//函數作用:NULL
//備注:NULL
/*****************************************************************/
void PullService::stopFramework()
{
    if(usingEventAdmin)
    {
        ctkPluginFrameworkLauncher::stop();
    }
    else
    {
        QSharedPointer<ctkPluginFramework> framework = frameworkFactory.getFramework();
        framework->stop();
    }
}



/*****************************************************************/
//作者:朱小勇
//函數名稱:內部打印函數
//函數參數:NULL
//函數返回值:NULL
//函數作用:NULL
//備注:NULL
/*****************************************************************/
void PullService::print(QString info)
{
    QString _i = QString("%1  %2  %3")
            .arg(__FILE__)
            .arg(QTime::currentTime().toString("HH:mm:ss"))
            .arg(info);
    qDebug()<<_i;
}

3、main.cpp

#include <QApplication>//本地頭文件
#include "pullservice.h"

int main(int argc, char *argv[])
{
    QApplication  a(argc, argv);
    (void)PullService::getInstance()->initCtkFramework(false);
    (void)PullService::getInstance()->initServices();
    return a.exec();
}

4、運行結果

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM