国内外基于vue框架的网站建设现状,wordpress水印插件,做国际网站每年要多少钱,wordpress免费的可视化编辑CTK插件框架学习-事件监听(04)https://mp.csdn.net/mp_blog/creation/editor/137171155
一、主要流程
信号发送者告诉服务要发送的信号信号发送者发送信号信号接收者告诉服务当触发某个订阅的主题时通知槽函数信号接收者处理槽函数信号槽参数类型必须为#xff08;const ctk…CTK插件框架学习-事件监听(04)https://mp.csdn.net/mp_blog/creation/editor/137171155
一、主要流程
信号发送者告诉服务要发送的信号信号发送者发送信号信号接收者告诉服务当触发某个订阅的主题时通知槽函数信号接收者处理槽函数信号槽参数类型必须为const ctkEvent
二、发布订阅插件 2.1、信号发送插件 发送信号类
SendSignal.h
#pragma once#include qobject.h
#include qstring.h
#include service/event/ctkEventAdmin.htypedef struct
{QString _name;QString _message;
}ST_Msg;class ctkPluginContext;
class SendSignal: public QObject
{Q_OBJECTpublic:SendSignal(ctkPluginContext* context);void publishMessage(const ST_Msg msg);signals:void sigSendMessage(const ctkDictionary dic);private:ctkPluginContext* m_context;
};SendSignal.cpp#include SendSignal.h
#include qdebug.h#include service/event/ctkEventAdmin.h
#include ctkPluginContext.hSendSignal::SendSignal(ctkPluginContext * context):m_context(context)
{ctkServiceReference ref context-getServiceReferencectkEventAdmin();if (ref){ctkEventAdmin* eventAdmin context-getServicectkEventAdmin(ref);if (eventAdmin){eventAdmin-publishSignal(this, SIGNAL(sigSendMessage(const ctkDictionary)), SIGNAL_MESSAGE, Qt::DirectConnection);}}
}void SendSignal::publishMessage(const ST_Msg msg)
{ctkDictionary dic;dic[name] msg._name;dic[message] msg._message;ctkEvent event(SIGNAL_MESSAGE, dic);qDebug() SendSignal message: dic;emit sigSendMessage(dic);}触发器类
PluginActivator.h
#pragma once
#include qobject.h
#include ctkPluginActivator.h
#include ctkPluginContext.h#include SendSignal.hclass PluginActivator :public QObject, ctkPluginActivator
{Q_OBJECTQ_INTERFACES(ctkPluginActivator)//向Qt的插件框架声明希望将xxx插件放入到框架中。Q_PLUGIN_METADATA(IID TestSignalPlugin)//向qt框架申明插件qt5版本public:PluginActivator();virtual void start(ctkPluginContext* context);virtual void stop(ctkPluginContext* context);private:QScopedPointerSendSignal m_sendSignal;//智能指针,自动析构回收
};PluginActivator.cpp#include PluginActivator.h
#include qdebug.h#include ctkPluginFrameworkLauncher.hPluginActivator::PluginActivator()
{
}void PluginActivator::start(ctkPluginContext* context)
{qDebug() my TestSignalPlugin start;m_sendSignal.reset(new SendSignal(context));ST_Msg msg;msg._name SendSignal;msg._message hello Signal send message;m_sendSignal-publishMessage(msg);ctkPlugin::State sta context-getPlugin()-getState();
}void PluginActivator::stop(ctkPluginContext* context)
{qDebug() my TestSignalPlugin stop;Q_UNUSED(context)// Q_UNUSED,如果一个函数的有些参数没有用到、某些变量只声明不使用但是又不想编译器、编辑器报警报其他没有什么实际性作用m_sendSignal.reset(NULL);ctkPlugin::State sta context-getPlugin()-getState();
}2.2、信号接收插件 接收信号类
ReceiveSlot.h
#pragma once#include qobject.h
#include qstring.h
#include service/event/ctkEventAdmin.hclass ctkPluginContext;
class ReceiveSlot: public QObject
{Q_OBJECTpublic:ReceiveSlot(ctkPluginContext* context);public slots:void slotReceiveMessage(const ctkEvent event);private:ctkPluginContext* m_context;
};ReceiveSlot.cpp#include ReceiveSlot.h
#include qdebug.h#include service/event/ctkEventAdmin.h
#include ctkPluginContext.hReceiveSlot::ReceiveSlot(ctkPluginContext * context):m_context(context)
{}void ReceiveSlot::slotReceiveMessage(const ctkEvent event)
{QString name event.getProperty(name).toString();QString message event.getProperty(message).toString();qDebug() ReceiveSlot name: name;qDebug() ReceiveSlot message: message;
}触发器类
PluginActivator.h
#pragma once
#include qobject.h
#include ctkPluginActivator.h
#include ctkPluginContext.h#include ReceiveSlot.hclass PluginActivator :public QObject, ctkPluginActivator
{Q_OBJECTQ_INTERFACES(ctkPluginActivator)//向Qt的插件框架声明希望将xxx插件放入到框架中。Q_PLUGIN_METADATA(IID TestSignalPlugin)//向qt框架申明插件qt5版本public:PluginActivator();virtual void start(ctkPluginContext* context);virtual void stop(ctkPluginContext* context);private:QScopedPointerReceiveSlot m_receiveSlot;//智能指针,自动析构回收
};PluginActivator.cpp#include PluginActivator.h
#include qdebug.h#include ctkPluginFrameworkLauncher.h#include service/event/ctkEventConstants.h
#include service/event/ctkEventAdmin.hPluginActivator::PluginActivator()
{
}void PluginActivator::start(ctkPluginContext* context)
{qDebug() my TestSlotPlugin start;m_receiveSlot.reset(new ReceiveSlot(context));ctkDictionary dic;dic[ctkEventConstants::EVENT_TOPIC] SIGNAL_MESSAGE;//订阅主题ctkServiceReference ref context-getServiceReferencectkEventAdmin();if (ref){ctkEventAdmin* eventAdmin context-getServicectkEventAdmin(ref);if (eventAdmin){eventAdmin-subscribeSlot(m_receiveSlot.get(), SLOT(slotReceiveMessage(const ctkEvent)), dic, Qt::DirectConnection);}}ctkPlugin::State sta context-getPlugin()-getState();
}void PluginActivator::stop(ctkPluginContext* context)
{qDebug() my TestSlotPlugin stop;Q_UNUSED(context)// Q_UNUSED,如果一个函数的有些参数没有用到、某些变量只声明不使用但是又不想编译器、编辑器报警报其他没有什么实际性作用m_receiveSlot.reset(NULL);ctkPlugin::State sta context-getPlugin()-getState();
}
2.3、测试插件
#include CTKPlugin.h
#include QtWidgets/QApplication#include iostream
#include QStyleFactory
#include QDir
#include QDirIterator
#include QDebug
#include ctkPluginFrameworkFactory.h
#include ctkPluginFramework.h
#include ctkPluginException.h
#include ctkPluginContext.h
#include ctkPluginFrameworkLauncher.h
#include ../TestPlugin/iTestPlugin.h
#include ../TestPlugin2/IService1.h
#include ../TestPlugin2/IService2.h
#include ../TestPlugin3/IService.h
/*
* 1、注意Plugin-SymbolicName要满足这里的前缀是TARGET/META-INF格式。TARGET的名字最好和工程名一致不然可能出现device not open错误。
* 2、如果CTK初始化、插件安装启动等是在一个类中则与CTK相关的变量应定义成类的属性不能是成员变量否则获取不到服务
* 3、CTK插件组成
1每个插件有自己的注册器Activator继承自QObject和ctkPluginActivator的一个类并实现ctkPluginActivator的start、stop函数
2每个插件必须有一个资源文件名称一般与插件名称一致前缀必须为TARGET/META-INF例插件名称/META-INF
3每个插件必须添加一个元数据文件名字必须为MANIFEST.MF并添加到资源文件中
* 4、QSharedPointer framework这个对象既可以作为对象也可以作为对象指针但要作为插件框架使用必须要用指针方法调用
* 5、生成的插件名(TARGET)不要有下划线因为CTK会默认将插件名中的下划线替换成点号最后导致找不到插件
*/
int main(int argc, char *argv[])
{QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QApplication a(argc, argv);a.setApplicationName(ctktest);//Linux下没有名称报错QString path QCoreApplication::applicationDirPath();#ifdef _DEBUGctkPluginFrameworkLauncher::addSearchPath(path /CTKPlugins);
#elsectkPluginFrameworkLauncher::addSearchPath(path /CTKPlugins);
#endif // _DEBUG// 设置并启动 CTK 插件框架try {ctkPluginFrameworkLauncher::start(org.commontk.eventadmin);}catch (ctkException e){std::cout e.message().toStdString() std::endl;}// 启动插件工厂ctkPluginFrameworkFactory* ctkFrameWorkFactory new ctkPluginFrameworkFactory;QSharedPointerctkPluginFramework framework ctkFrameWorkFactory-getFramework();try {framework-init();framework-start();}catch (const ctkPluginException e){std::cout framework init fail std::endl;}QSharedPointerctkPlugin plugin;/*
* 使用MANIFEST.MF启动依赖插件方法未成功采用独立加载插件方法
*/
#if 0QDirIterator iter(path /plugins/, { *.dll }, QDir::NoFilter, QDirIterator::Subdirectories);while (iter.hasNext()) {//qDebug() iter.next();QString dllPath iter.next();QUrl url QUrl::fromLocalFile(dllPath);try{plugin framework-getPluginContext()-installPlugin(url);qDebug() QString(Plugin[%1_%2] installed...).arg(plugin-getSymbolicName()).arg(plugin-getVersion().toString());//获取MANIFEST.MF中的数据QHashQString, QString headers plugin-getHeaders();ctkVersion version ctkVersion::parseVersion(headers.value(ctkPluginConstants::PLUGIN_VERSION));QString name headers.value(ctkPluginConstants::PLUGIN_NAME);}catch (ctkPluginException e) {std::cout e.message().toStdString() e.getType() std::endl;}try {plugin-start(ctkPlugin::START_TRANSIENT);//表示立即启用插件不设置参数的话加载后也不会立即打印输出qDebug() QString(Plugin[%1_%2] started).arg(plugin-getSymbolicName()).arg(plugin-getVersion().toString());}catch (ctkPluginException e) {std::cout e.message().toStdString() e.getType() std::endl;}}#elsetry{QUrl url QUrl::fromLocalFile(path /plugins/TestSlotPlugin.dll);plugin framework-getPluginContext()-installPlugin(url);qDebug() QString(Plugin[%1_%2] installed...).arg(plugin-getSymbolicName()).arg(plugin-getVersion().toString());//获取MANIFEST.MF中的数据QHashQString, QString headers plugin-getHeaders();ctkVersion version ctkVersion::parseVersion(headers.value(ctkPluginConstants::PLUGIN_VERSION));QString name headers.value(ctkPluginConstants::PLUGIN_NAME);}catch (ctkPluginException e) {std::cout e.message().toStdString() e.getType() std::endl;}try {plugin-start(ctkPlugin::START_TRANSIENT);//表示立即启用插件不设置参数的话加载后也不会立即打印输出qDebug() QString(Plugin[%1_%2] started).arg(plugin-getSymbolicName()).arg(plugin-getVersion().toString());}catch (ctkPluginException e) {std::cout e.message().toStdString() e.getType() std::endl;}try{QUrl url QUrl::fromLocalFile(path /plugins/TestSignalPlugin.dll);plugin framework-getPluginContext()-installPlugin(url);qDebug() QString(Plugin[%1_%2] installed...).arg(plugin-getSymbolicName()).arg(plugin-getVersion().toString());//获取MANIFEST.MF中的数据QHashQString, QString headers plugin-getHeaders();ctkVersion version ctkVersion::parseVersion(headers.value(ctkPluginConstants::PLUGIN_VERSION));QString name headers.value(ctkPluginConstants::PLUGIN_NAME);}catch (ctkPluginException e) {std::cout e.message().toStdString() e.getType() std::endl;}try {plugin-start(ctkPlugin::START_TRANSIENT);//表示立即启用插件不设置参数的话加载后也不会立即打印输出qDebug() QString(Plugin[%1_%2] started).arg(plugin-getSymbolicName()).arg(plugin-getVersion().toString());}catch (ctkPluginException e) {std::cout e.message().toStdString() e.getType() std::endl;}
#endif//ctkPlugin::State sta plugin-getState();//ctkPluginFrameworkLauncher::stop();//plugin-stop(); //plugin-uninstall();//sta plugin-getState();CTKPlugin c;c.show();return a.exec();
}三、类通信和信号槽区别
1、使用event发送效率优于信号槽信号槽方式会在qt信号槽机制中转再发送到ctk框架
2、两种方式可以混合使用
3、同步sendEvent / Qt::DirectConnection
4、异步postEvent / Qt::QueuedConnection