CTK框架(七):事件监听
目录
1.概述
2.监听接口
3.具体实现
1.概述
CTK(Common Toolkit)框架中的事件监听机制是一个重要的功能,它允许开发者在特定事件发生时接收到通知并执行相应的操作。CTK框架主要支持三种类型的事件监听:框架事件、插件事件和服务事件。但是这些事件只有再变化时才能监听到,如果已经变化过后,进入一个稳定的状态,这时才去监听,那么是无法监听到的。以下是对这三种事件监听的详细解析:
框架事件
针对整个框架的,相当于只有一个,因为框架只有一个,但是这里有个问题,就是监听这个事件是在框架初始化之后的,所以根本没法监听到框架事件的初始化,只能监听到结束的事件。常见的框架事件包括:
- RAMEWORK_STARTED:框架已经启动。
- PLUGIN_ERROR:插件执行过程中发生错误。
- PLUGIN_WARNING:插件执行过程中产生警告。
- PLUGIN_INFO:插件的某种信息性事件。
- FRAMEWORK_STOPPED:框架已经被停止。
- FRAMEWORK_STOPPED_UPDATE:框架在更新过程中停止。
- FRAMEWORK_WAIT_TIMEDOUT:在等待超时过期之前,框架没有停止。
插件事件
插件事件与插件的安装、启动、停止和卸载等过程紧密相关。常见的插件事件包括:
- INSTALLED:插件已经被安装。
- RESOLVED:插件已经被解析。
- LAZY_ACTIVATION:插件将被惰性激活。
- STARTING:插件即将被激活。
- STARTED:插件已经被启动。
- STOPPING:插件即将停用。
- STOPPED:插件已经被停止。
- UPDATED:插件已经被更新。
- UNRESOLVED:插件无法被解析。
- UNINSTALLED:插件已经被卸载。
通过监听插件事件,开发者可以实时掌握插件的状态变化,并进行相应的处理。
服务事件
服务事件主要涉及服务的注册、注销和属性变化等。常见的服务事件包括:
- REGISTERED:服务已经被注册。
- MODIFIED:已注册服务的属性被修改。
- MODIFIED_ENDMATCH:已注册服务的属性已被修改,并且新属性不再与侦听器的筛选器匹配。
- UNREGISTERING:此服务正在注销过程中。
通过监听服务事件,开发者可以了解到服务的生命周期状态,并在必要时采取相应的措施。
2.监听接口
主要是ctkPluginContext提供的六个函数:
class CTK_PLUGINFW_EXPORT ctkPluginContext
{
//...
public:
bool connectPluginListener(const QObject* receiver, const char* slot, Qt::ConnectionType type = Qt::QueuedConnection);
void disconnectPluginListener(const QObject* receiver, const char* slot = 0);
bool connectFrameworkListener(const QObject* receiver, const char* slot, Qt::ConnectionType type = Qt::QueuedConnection);
void disconnectFrameworkListener(const QObject* receiver, const char* slot = 0);
void connectServiceListener(QObject* receiver, const char* slot,
const QString& filter = QString());
void disconnectServiceListener(QObject* receiver, const char* slot);
//...
};
在CTK框架中,事件监听通常通过实现相应的监听器接口并在适当的时机注册监听器来实现。监听器可以通过框架提供的接口(如ctkPluginContext
)连接到事件源,以便在事件发生时接收到通知。
此外,CTK框架还支持通过ctkEventAdmin
服务进行事件发布和订阅,这是一种更加灵活和强大的事件通信方式。通过ctkEventAdmin
,开发者可以定义自定义事件并控制事件的发送和接收。
3.具体实现
以下是一个简单的示例,展示了如何在CTK框架中注册事件监听器:
#include <QObject>
#include <ctkPluginFrameworkEvent.h>
#include <ctkPluginEvent.h>
#include <ctkServiceEvent.h>
class EventListener : public QObject {
Q_OBJECT
public:
explicit EventListener(ctkPluginContext* context, QObject *parent = nullptr);
public slots:
void onFrameworkEvent(const ctkPluginFrameworkEvent &event);
void onPluginEvent(const ctkPluginEvent &event);
void onServiceEvent(const ctkServiceEvent &event);
};
EventListener::EventListener(ctkPluginContext* context, QObject *parent) : QObject(parent) {
// 假设已有ctkPluginContext *context可用
context->connectFrameworkListener(this, SLOT(onFrameworkEvent(ctkPluginFrameworkEvent)));
context->connectPluginListener(this, SLOT(onPluginEvent(ctkPluginEvent)));
context->connectServiceListener(this, SLOT(onServiceEvent(ctkServiceEvent)));
}
void EventListener::onFrameworkEvent(const ctkPluginFrameworkEvent &event) {
// 处理框架事件
if (!event.isNull()) {
QSharedPointer<ctkPlugin> plugin = event.getPlugin();
std::cout << "FrameworkEvent: [" << plugin->getSymbolicName().toStdString() << "]"
<< event.getType() << event.getErrorString().toStdString() << std::endl;
} else {
std::cout << "The framework event is null" << std::endl;
}
}
void EventListener::onPluginEvent(const ctkPluginEvent &event) {
// 处理插件事件
if (!event.isNull()) {
QSharedPointer<ctkPlugin> plugin = event.getPlugin();
std::cout << "PluginEvent: [" << plugin->getSymbolicName().toStdString() << "]"
<< event.getType() << std::endl;
} else {
std::cout << "The plugin event is null" << std::endl;
}
}
void EventListener::onServiceEvent(const ctkServiceEvent &event) {
// 处理服务事件
if (!event.isNull()) {
ctkServiceReference ref = event.getServiceReference();
QSharedPointer<ctkPlugin> plugin = ref.getPlugin();
for(const auto &pluginD : ref.getUsingPlugins())
{
std::cout << "ServiceEvent: [" << plugin->getSymbolicName().toStdString() << "]"
<< event.getType() << pluginD->getSymbolicName().toStdString() << std::endl;
}
} else {
std::cout << "The service event is null" << std::endl;
}
}
将监听在main函数中加上
// 事件监听
EventListener listener(pluginContext);
之后运行代码即可监听到对应的信息。