CTK 事件管理机制(signal/slot)
来源:互联网 发布:来自mac的照片怎么删除 编辑:程序博客网 时间:2024/06/09 16:25
简述
在 CTK 中,插件之间的通信,可以通过 Event Admin
来完成。Event Admin
是一种基于发布/订阅的方式,一个插件订阅某一主题之后,另一个插件发布一个与该主题相关的事件,从而达到通信的目的。
除了 CTK 事件管理机制(sendEvent()/postEvent()) 中介绍的 sendEvent()/postEvent() + ctkEventHandler
方式之外,Event Admin
还提供了另一种方式 - signal/slot
,可以达到相同的效果。
- 简述
- 使用事件管理机制
- 工程文件
- 事件发布者
- 事件处理程序
- 主程序
- 比较
版权所有:一去丶二三里,转载请注明出处:http://blog.csdn.net/liang19890820
使用事件管理机制
下面,来演示 signal/slot
方式:
工程文件
创建一个 Qt 控制台应用程序,.pro
内容如下:
QT += coreQT -= guiTARGET = PublishSignalCONFIG += consoleTEMPLATE = appLIBS += -L$$PWD/Libs -lCTKCore -lCTKPluginFrameworkINCLUDEPATH += \ $$PWD/../../../CTK-master/Libs/Core \ $$PWD/../../../CTK-master/Libs/PluginFrameworkHEADERS += \ publisher.h \ subscriber.hSOURCES += \ main.cpp \ publisher.cpp \ subscriber.cpp
需要同时包含 CTKCore
和 CTKPluginFramework
。
事件发布者
使用 Qt 信号来发布事件需要声明一个 signal
,并使用 Event Admin
注册(发布)它。
publisher.h
内容如下:
#ifndef PUBLISHER_H#define PUBLISHER_H#include <QObject>#include <ctkPluginContext.h>#include <service/event/ctkEventAdmin.h>// 事件发布者class Publisher : public QObject{ Q_OBJECTpublic: Publisher(ctkPluginContext* context); // 使用一个特定的主题来注册信号 void publishSignal(); // 发布事件 void publish();signals: void finished(const ctkDictionary&);private: ctkPluginContext* pc;};#endif // PUBLISHER_H
使用一个特定的主题来注册信号(发射信号将始终发送 ctkEvent
对象,该对象将此主题作为 EVENT_TOPIC
属性)。
publisher.cpp
内容如下:
#include "publisher.h"Publisher::Publisher(ctkPluginContext *context) : pc(context){}// 使用一个特定的主题来注册信号void Publisher::publishSignal(){ ctkServiceReference ref = pc->getServiceReference<ctkEventAdmin>(); if (ref) { ctkEventAdmin* eventAdmin = pc->getService<ctkEventAdmin>(ref); eventAdmin->publishSignal(this, SIGNAL(finished(ctkDictionary)), "org/commontk/login", Qt::DirectConnection); }}// 发布事件void Publisher::publish(){ ctkDictionary props; props.insert("name", "Waleon"); props.insert("age", 18); emit finished(props);}
发射信号将自动创建一个 ctkEvent
对象,同步或异步发送,取决于发射信号时使用的 Qt:ConnectionType
。
事件处理程序
以 ctkEvent
对象作为参数的每个 Qt 槽,都可以被订阅来接收事件通知。
subscriber.h
内容如下:
#ifndef SUBSCRIBER_H#define SUBSCRIBER_H#include <QObject>#include <ctkPluginContext.h>#include <service/event/ctkEvent.h>// 事件处理程序(或订阅者)class Subscriber : public QObject{ Q_OBJECTpublic: Subscriber(ctkPluginContext* context); // 可以被订阅,来接收事件通知 void subscribeSlot();private slots: // 处理事件 void onFinished(const ctkEvent& event);private: ctkPluginContext* pc;};#endif // SUBSCRIBER_H
subscriber.cpp
内容如下:
#include "subscriber.h"#include <QDebug>#include <service/event/ctkEventConstants.h>#include <service/event/ctkEventAdmin.h>Subscriber::Subscriber(ctkPluginContext* context) : QObject(), pc(context){}// 可以被订阅,来接收事件通知void Subscriber::subscribeSlot(){ ctkDictionary props; props[ctkEventConstants::EVENT_TOPIC] = "org/commontk/login"; ctkServiceReference ref = pc->getServiceReference<ctkEventAdmin>(); if (ref) { ctkEventAdmin* eventAdmin = pc->getService<ctkEventAdmin>(ref); eventAdmin->subscribeSlot(this, SLOT(onFinished(ctkEvent)), props); }}// 处理事件void Subscriber::onFinished(const ctkEvent& event){ QString name = event.getProperty("name").toString(); int age = event.getProperty("age").toInt(); qDebug() << QString("name:%1 age:%2").arg(name).arg(age);}
使用 Qt 槽作为事件处理程序,可以很容易地确保事件处理代码在接收者的线程中执行(默认的连接类型是 Qt::AutoConnection
)。
主程序
最后,来看看 main.cpp
:
#include <QCoreApplication>#include <ctkPluginFrameworkLauncher.h>#include <ctkPluginContext.h>#include "publisher.h"#include "subscriber.h"// liborg_commontk_eventadmin.dll 所在路径const QString c_strSearchPath = "E:/CTK-Examples/EventAdmin/PublishSignal/Plugins";int main(int argc, char *argv[]){ QCoreApplication app(argc, argv); // 在插件的搜索路径列表中添加一条路径 ctkPluginFrameworkLauncher::addSearchPath(c_strSearchPath); // 设置并启动 CTK 插件框架 ctkPluginFrameworkLauncher::start("org.commontk.eventadmin"); // 获取插件上下文 ctkPluginContext* pluginContext = ctkPluginFrameworkLauncher::getPluginContext(); // 订阅接收事件 Subscriber sub(pluginContext); sub.subscribeSlot(); Publisher pub(pluginContext); // 使用一个特定的主题来注册信号 pub.publishSignal(); // 发布事件 pub.publish(); // 停止插件 ctkPluginFrameworkLauncher::stop(); return app.exec();}
好了,此过程在前面已经讲过,这里就不再赘述。
比较
回过头来,比较下这两种方式:
sendEvent()/postEvent() + ctkEventHandler
signal/slot
使用 Qt 信号,可以简化发送事件的行为。然而,由于信号发射需要经过 Qt 元对象系统,所以其性能较差。此外,信号被绑定到一个特定的事件主题上。
使用 ctkEventHandler
接口或 Qt 槽来注册一个事件处理程序,涉及的代码量大致相同。然而,使用槽会降低性能(可能会被忽略不计),但是代码将自动与接收者线程同步。
此外,订阅槽意味着需要一个已注册的事件管理服务实现。而 ctkEventHandler
方式不需要了解 Event Admin
的任何信息,因为 handler 被注册为框架中的一个服务对象。
- CTK 事件管理机制(signal/slot)
- CTK 事件管理机制(sendEvent()/postEvent())
- Boost 的事件管理架構:Signal / Slot(上)
- Boost 的事件管理架構:Signal / Slot(中)
- Boost 的事件管理架構:Signal / Slot(下)
- QT中的signal/slot的事件
- Signal & Slot
- Boost 的事件管理架構:Signal / Slot(上)
- 信号(SIGNAL)与槽(SLOT)
- QT值SIGNAL() 和 SLOT()
- 信号和槽机制(Signal & Slot)
- Boost 的事件管理架構:Signal / Slot
- 深入理解QT的SIGNAL\SLOT机制(一):SIGNAL\SLOT如何使用
- boost--signal--slot笔记
- Scim Signal/Slot
- QObject-Signal-Slot
- qt signal and slot
- C++ slot signal机制
- SpringBoot 统一异常处理
- Practical Derivatives
- phpstudy本地配置虚拟主机教程You don't have permission to access解决
- 问题小结
- y400安装dolby方法
- CTK 事件管理机制(signal/slot)
- 学习笔记:前端软件汇总
- kvm虚拟机迁移/克隆kvm虚拟机
- activiti新手入门(三)--准备activiti的开发环境
- TensorFlow官方文档中文版-笔记(八)
- xhsell 产品注册码
- Tylor Expansion Example
- 热血传奇客户端wil文件中文含义详解
- Python 如何绘制圆,Python绘制圆(超棒!!)