CTK 插件之间通信

一、类通信

1、事件发布类

.h文件  

#ifndef BLOGMANAGER_H
#define BLOGMANAGER_H

#include "ctkPluginContext.h"

typedef struct Blog_Info{
    QString title;
    QString author;
    QString content;
} Blog;
class BlogManager
{
public:
    BlogManager(ctkPluginContext *context);
    void publishBlog(const Blog &blog);

private:
    ctkPluginContext *m_pContext;
};

#endif // BLOGMANAGER_H

.cpp

#include "blogmanager.h"
#include <service/event/ctkEventAdmin.h>
#include <QtDebug>

BlogManager::BlogManager(ctkPluginContext *context): m_pContext(context)
{

}

void BlogManager::publishBlog(const Blog &blog)
{
    qDebug() << "asdf";
    ctkServiceReference ref = m_pContext->getServiceReference<ctkEventAdmin>();
    if(ref)
    {
        qDebug() << "asafegdbgdf";
        ctkEventAdmin *eventAdmin = m_pContext->getService<ctkEventAdmin>(ref);
        ctkDictionary props;
        props["title"] = blog.title;
        props["author"] = blog.author;
        props["content"] = blog.content;
        ctkEvent event("org/commontk/bloggenerator/published", props);
        qDebug() << "Publisher sends a message, properties:" << props;
        eventAdmin->sendEvent(event);
    }
}

.h文件 激活类

#ifndef ACTIVATOR_H
#define ACTIVATOR_H

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

class Activator : public QObject,public ctkPluginActivator
{
    Q_OBJECT
    Q_INTERFACES(ctkPluginActivator)
    Q_PLUGIN_METADATA(IID "activator")
public:
    Activator();
    void start(ctkPluginContext *context);
    void stop(ctkPluginContext *context);

private:
    BlogManager *m_blog;
};

#endif // ACTIVATOR_H

.cpp文件

#include "activator.h"
#include <QDebug>

Activator::Activator()
{

}

void Activator::start(ctkPluginContext *context)
{
    qDebug() << "Plugin";
    m_blog = new BlogManager(context);
    Blog blog;
    blog.title = "honghuang";
    blog.author = "czw";
    blog.content = "jilurensheng";
    m_blog->publishBlog(blog);
    qDebug() << "xxx";
}

void Activator::stop(ctkPluginContext *context)
{
    Q_UNUSED(context)
    delete m_blog;
}

.pro文件

QT += core
QT -= gui

TARGET = SendClass
TEMPLATE = lib
CONFIG += plugin

# ctk源码路径
INCLUDEPATH += C:/Users/ch-pc/Desktop/CTK-master/Libs/Core \
            += C:/Users/ch-pc/Desktop/CTK-master/Libs/PluginFramework
# ctk安装路径,主要用到的头文件等
INCLUDEPATH += C:/Users/ch-pc/Desktop/CTK-master/build_MSVC2017_64/CTK-build/Libs/PluginFramework
INCLUDEPATH += C:/Users/ch-pc/Desktop/CTK-master/build_MSVC2017_64/CTK-build/Libs/Core
# ctk动态库路径
LIBS += -LC:/Users/ch-pc/Desktop/CTK-master/build_MSVC2017_64/CTK-build/bin/Debug -lCTKCore -lCTKPluginFramework

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked 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 it uses 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


HEADERS += \
    blogmanager.h \
    activator.h

SOURCES += \
    blogmanager.cpp \
    activator.cpp

RESOURCES += \
    pro.qrc

 

2、接收事件类

.h文件  接收事件

#ifndef BLOGEVENTHANDLE_H
#define BLOGEVENTHANDLE_H

#include <QObject>
#include <service/event/ctkEventHandler.h>

class BlogEventHandle : public QObject,public ctkEventHandler
{
    Q_OBJECT
    Q_INTERFACES(ctkEventHandler)
public:
    BlogEventHandle();
    void handleEvent(const ctkEvent& event) Q_DECL_OVERRIDE;
};

#endif // BLOGEVENTHANDLE_H

.cpp文件

#include "blogeventhandle.h"

BlogEventHandle::BlogEventHandle()
{

}

void BlogEventHandle::handleEvent(const ctkEvent &event)
{
    QString title = event.getProperty("title").toString();
    QString content = event.getProperty("content").toString();
    QString author = event.getProperty("author").toString();
    qDebug() << "EventHandler received the message, topic:" <<
    event.getTopic()
    << "properties:" << "title:" << title << "content:" << content
    << "author:" << author;
}

.h文件 激活类

#ifndef ACTIVATOR_H
#define ACTIVATOR_H

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

class Activator : public QObject,public ctkPluginActivator
{
    Q_OBJECT
    Q_INTERFACES(ctkPluginActivator)
    Q_PLUGIN_METADATA(IID "recv")
public:
    Activator();
    void start(ctkPluginContext *context);
    void stop(ctkPluginContext *context);

private:
    BlogEventHandle *m_log;
};

#endif // ACTIVATOR_H

.cpp文件

#include "activator.h"
#include <QtDebug>
#include <service/event/ctkEventConstants.h>

Activator::Activator()
{

}

void Activator::start(ctkPluginContext *context)
{
    qDebug() << "recv start";
    m_log = new BlogEventHandle();
    ctkDictionary pros;
    pros[ctkEventConstants::EVENT_TOPIC] = "org/commontk/bloggenerator/published";
    pros[ctkEventConstants::EVENT_FILTER] = "(author=czw)";
    context->registerService<ctkEventHandler>(m_log, pros);
}

void Activator::stop(ctkPluginContext *context)
{
    Q_UNUSED(context)
    delete m_log;
}

 

.pro文件

QT += core
QT -= gui

TARGET = RecvClass
TEMPLATE = lib
CONFIG += plugin

# ctk源码路径
INCLUDEPATH += C:/Users/ch-pc/Desktop/CTK-master/Libs/Core \
            += C:/Users/ch-pc/Desktop/CTK-master/Libs/PluginFramework
# ctk安装路径,主要用到的头文件等
INCLUDEPATH += C:/Users/ch-pc/Desktop/CTK-master/build_MSVC2017_64/CTK-build/Libs/PluginFramework
INCLUDEPATH += C:/Users/ch-pc/Desktop/CTK-master/build_MSVC2017_64/CTK-build/Libs/Core
# ctk动态库路径
LIBS += -LC:/Users/ch-pc/Desktop/CTK-master/build_MSVC2017_64/CTK-build/bin/Debug -lCTKCore -lCTKPluginFramework

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked 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 it uses 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

HEADERS += \
    blogeventhandle.h \
    activator.h

SOURCES += \
    blogeventhandle.cpp \
    activator.cpp

RESOURCES += \
    pro.qrc

3、在每个插件上都要加一个资源文件  前缀:/插件名/META-INF  文件:MANIFEST.MF

Plugin-SymbolicName:“插件名”
Plugin-Version:1.0.0    //版本号

4、客户端

#include <QCoreApplication>
#include <QtDebug>
#include <ctkPluginFrameworkLauncher.h>
#include <ctkPluginContext.h>
#include <ctkPluginException.h>
int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    // 获取插件所在位置
    QString path = QCoreApplication::applicationDirPath();
    // 在插件的搜索路径列表中添加一条路径
    ctkPluginFrameworkLauncher::addSearchPath(path);
    // 设置并启动 CTK 插件框架
    ctkPluginFrameworkLauncher::start("org.commontk.eventadmin");
    // 获取插件上下文
    ctkPluginContext* context = ctkPluginFrameworkLauncher::getPluginContext();
    // 启动插件 BlogEventHandlerUsingSlots
    try {
        // 安装插件
        QSharedPointer<ctkPlugin> plugin = context->installPlugin(QUrl::fromLocalFile(path + "/RecvClass.dll"));
        qDebug() << QString("Plugin[%1_%2] installed...").arg(plugin->getSymbolicName()).arg(plugin->getVersion().toString());
        plugin->start(ctkPlugin::START_TRANSIENT);
        qDebug() << "BlogEventHandlerUsingSlots start ...";
    } catch (const ctkPluginException &e) {
        qDebug() << "Failed to start BlogEventHandlerUsingSlots" << e.what();
        return -1;
    }
    // 启动插件 BlogManagerUsingSignals
    try {
        QSharedPointer<ctkPlugin> plugin = context->installPlugin(QUrl::fromLocalFile(path + "/SendClass.dll"));
        qDebug() << QString("Plugin[%1_%2] installed...").arg(plugin->getSymbolicName()).arg(plugin->getVersion().toString());

        plugin->start(ctkPlugin::START_TRANSIENT);
        qDebug() << "BlogManagerUsingSignals start ...";
    } catch (const ctkPluginException &e) {
        qDebug() << "Failed to start BlogManagerUsingSignals" << e.what();
        return -1;
    }
    // 停止插件
    ctkPluginFrameworkLauncher::stop();
    return app.exec();
    }

.pro文件

QT -= gui

CONFIG += c++11 console
CONFIG -= app_bundle

# ctk源码路径
INCLUDEPATH += C:/Users/ch-pc/Desktop/CTK-master/Libs/Core \
            += C:/Users/ch-pc/Desktop/CTK-master/Libs/PluginFramework
# ctk安装路径,主要用到的头文件等
INCLUDEPATH += C:/Users/ch-pc/Desktop/CTK-master/build_MSVC2017_64/CTK-build/Libs/PluginFramework
INCLUDEPATH += C:/Users/ch-pc/Desktop/CTK-master/build_MSVC2017_64/CTK-build/Libs/Core
# ctk动态库路径
LIBS += -LC:/Users/ch-pc/Desktop/CTK-master/build_MSVC2017_64/CTK-build/bin/Debug -lCTKCore -lCTKPluginFramework


# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked 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 it uses 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

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

二、信号与槽通信

1、发布事件类

#ifndef BLOGMANAGERUSINGSIGNALS_H
#define BLOGMANAGERUSINGSIGNALS_H

#include <QObject>
#include <ctkPluginContext.h>
#include <service/event/ctkEventAdmin.h>

typedef struct Blog_Info{
    QString title;
    QString author;
    QString content;
} Blog;

class BlogManagerUsingSignals : public QObject
{
    Q_OBJECT
public:
    BlogManagerUsingSignals(ctkPluginContext* context);
    void publishBlog(const Blog& blog);

signals:
    void blogPublished(const ctkDictionary&);

private:
    ctkPluginContext *context;
};

#endif // BLOGMANAGERUSINGSIGNALS_H

.cpp文件

#include "blogmanagerusingsignals.h"

BlogManagerUsingSignals::BlogManagerUsingSignals(ctkPluginContext * context)
{
    ctkServiceReference ref = context->getServiceReference<ctkEventAdmin>();
    if(ref)
    {
        ctkEventAdmin * eventAdmin = context->getService<ctkEventAdmin>(ref);
        eventAdmin->publishSignal(this, SIGNAL(blogPublished(ctkDictionary)), "org/commontk/bloggenerator/published", Qt::DirectConnection);
    }
}

// 发布事件
void BlogManagerUsingSignals::publishBlog(const Blog &blog)
{
    ctkDictionary props;
    props["title"] = blog.title;
    props["author"] = blog.author;
    props["content"] = blog.content;
    qDebug() << "Publisher sends a message, properties:" << props;
    emit blogPublished(props);
}

.h文件

#ifndef BLOGMANAGERUSINGSIGNALSACTIVATOR_H
#define BLOGMANAGERUSINGSIGNALSACTIVATOR_H

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

class BlogManagerUsingSignalsActivator :public QObject, public ctkPluginActivator
{
    Q_OBJECT
    Q_INTERFACES(ctkPluginActivator)
    Q_PLUGIN_METADATA(IID "signal")
public:
    BlogManagerUsingSignalsActivator();
    void start(ctkPluginContext *context);
    void stop(ctkPluginContext *context);

private:
    BlogManagerUsingSignals *m_pBlog;
};

#endif // BLOGMANAGERUSINGSIGNALSACTIVATOR_H

.cpp文件

#include "blogmanagerusingsignalsactivator.h"
#include <QDebug>

BlogManagerUsingSignalsActivator::BlogManagerUsingSignalsActivator()
{

}

void BlogManagerUsingSignalsActivator::start(ctkPluginContext *context)
{
    m_pBlog = new BlogManagerUsingSignals(context);
    Blog blog;
    blog.title = "CTK Event Admin";
    blog.author = "czw";
    blog.content = "This is a simple blog";
    m_pBlog->publishBlog(blog);
}

void BlogManagerUsingSignalsActivator::stop(ctkPluginContext *context)
{
    Q_UNUSED(context)
    delete  m_pBlog;
}

2、接收事件类

.h文件

#ifndef BLOGEVENTHANDLERUSINGSLOTS_H
#define BLOGEVENTHANDLERUSINGSLOTS_H

#include <QObject>
#include <QDebug>
#include <service/event/ctkEvent.h>
#include <ctkPluginContext.h>

class BlogEventHandlerUsingSlots : public QObject
{
    Q_OBJECT
public:
    BlogEventHandlerUsingSlots(ctkPluginContext *context);

public slots:
    void onBlogPublished(const ctkEvent& event);
};

#endif // BLOGEVENTHANDLERUSINGSLOTS_H

.cpp文件

#include "blogeventhandlerusingslots.h"
#include "service/event/ctkEventConstants.h"
#include "service/event/ctkEventAdmin.h"

BlogEventHandlerUsingSlots::BlogEventHandlerUsingSlots(ctkPluginContext *context)
{
    ctkDictionary props;
    props[ctkEventConstants::EVENT_TOPIC] = "org/commontk/bloggenerator/published";
    ctkServiceReference ref = context->getServiceReference<ctkEventAdmin>();
    if (ref)
    {
        ctkEventAdmin* eventAdmin = context->getService<ctkEventAdmin>(ref);
        eventAdmin->subscribeSlot(this,SLOT(onBlogPublished(ctkEvent)), props, Qt::DirectConnection);
    }
}

void BlogEventHandlerUsingSlots::onBlogPublished(const ctkEvent &event)
{
    QString title = event.getProperty("title").toString();
    QString content = event.getProperty("content").toString();
    QString author = event.getProperty("author").toString();
    qDebug() << "EventHandler received the message, topic:" <<event.getTopic()<< "properties:" << "title:" << title << "content:" << content
    << "author:" << author;
}

.h文件  激活类

#ifndef BLOGEVENTHANDLERUSINGSLOTSACTIVATOR_H
#define BLOGEVENTHANDLERUSINGSLOTSACTIVATOR_H

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

class BlogEventHandlerUsingSlotsActivator : public QObject, public ctkPluginActivator
{
    Q_OBJECT
    Q_INTERFACES(ctkPluginActivator)
    Q_PLUGIN_METADATA(IID "slot")
public:
    BlogEventHandlerUsingSlotsActivator();
    void start(ctkPluginContext *context);
    void stop(ctkPluginContext *context);

private:
    QScopedPointer<BlogEventHandlerUsingSlots> m_log;
};

#endif // BLOGEVENTHANDLERUSINGSLOTSACTIVATOR_H

.cpp文件

#include "blogeventhandlerusingslotsactivator.h"
#include <service/event/ctkEventConstants.h>
#include <service/event/ctkEventAdmin.h>
#include <QDebug>

BlogEventHandlerUsingSlotsActivator::BlogEventHandlerUsingSlotsActivator()
{

}

void BlogEventHandlerUsingSlotsActivator::start(ctkPluginContext *context)
{
    m_log.reset(new BlogEventHandlerUsingSlots(context));
}

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

 

三、注意事项:

  注意在实现插件间通信时,需要先启动接收插件的dll,然后再启动发送事件的插件的dll

posted on 2020-08-07 17:17  缘随风烬  阅读(871)  评论(1编辑  收藏  举报