CTK插件框架学习-事件监听(07)

CTK插件框架学习-服务工厂(06)icon-default.png?t=N7T8https://mp.csdn.net/mp_blog/creation/editor/137295686

一、简介

事件监听指当事件发生变化时所产生的通信,是动态的,对于已经发生过的事件无法监听

二、事件类型

1、框架事件

监听框架状态变化,因为监听在框架初始化之后所以只能监听框架结束事件

事件类型
FRAMEWORK_STARTED
PLUGIN_ERROR
PLUGIN_WARNING
PLUGIN_INFO
FRAMEWORK_STOPPED
FRAMEWORK_STOPPED_UPDATE
FRAMEWORK_WAIT_TIMEDOUT

2、插件事件

监听插件状态变化,如插件安装,插件启动

事件类型
INSTALLED
RESOLVED
LAZY_ACTIVATION
STARTING
STARTED
STOPPING
STOPPED
UPDATED
UNRESOLVED
UNINSTALLED

3、服务事件

在服务内进行插件注册、销毁等触发

事件类型
REGISTERED
MODIFIED
MODIFIED_ENDMATCH
UNREGISTERING

三、监听功能测试

EventListener类

============================EventListener.h==================================
#pragma once
#include <QObject>
#include <ctkPluginFrameworkEvent.h>
#include <ctkPluginEvent.h>
#include <ctkServiceEvent.h>class EventListener :public QObject
{Q_OBJECTpublic:explicit EventListener(QObject *parent = Q_NULLPTR);~EventListener();public slots:void slotFrameWorkEvent(const ctkPluginFrameworkEvent& event);void slotPluginEvent(const ctkPluginEvent& event);void slotServiceEvent(const ctkServiceEvent & event);
};============================EventListener.cpp================================#include "EventListener.h"
#include <qdebug.h>EventListener::EventListener(QObject * parent)
{
}EventListener::~EventListener()
{
}void EventListener::slotFrameWorkEvent(const ctkPluginFrameworkEvent & event)
{if (event.isNull()){qDebug() << event.getPlugin()->getSymbolicName() << ": " << event.getErrorString();return;}qDebug() << event.getPlugin()->getSymbolicName() << ": " << event.getType();
}void EventListener::slotPluginEvent(const ctkPluginEvent & event)
{if (event.isNull()){qDebug() << event.getPlugin()->getSymbolicName() << "is null";return;}qDebug() << event.getPlugin()->getSymbolicName() << ": " << event.getType();
}void EventListener::slotServiceEvent(const ctkServiceEvent  & event)
{if (event.isNull()){		qDebug() << "ctkServiceEvent is null";return;}ctkServiceReference ref = event.getServiceReference();QSharedPointer<ctkPlugin> plugin = ref.getPlugin();qDebug() << plugin->getSymbolicName() << ": " << event.getType() << " usingPlugins:" << ref.getUsingPlugins();
}

main.cpp

#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 "EventListener.h"#include "../TestPlugin/iTestPlugin.h"
#include "../TestPlugin2/IService1.h"
#include "../TestPlugin2/IService2.h"
#include "../TestPlugin3/IService.h"
#include "../TestServiceFactory/IPrintfService.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");//ctkPluginFrameworkLauncher::addSearchPath("E:/Demo(Qt5)/08_CTKPlugin/CTKPlugin/CTK/lib/ctk-0.1/plugins");
#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;QSharedPointer<ctkPluginFramework> framework = ctkFrameWorkFactory->getFramework();try {framework->init();framework->start();}catch (const ctkPluginException& e){std::cout << "framework init fail" << std::endl;}//在框架初始化启动成功后再调用事件监听EventListener eventListener;framework->getPluginContext()->connectFrameworkListener(&eventListener, SLOT(slotFrameWorkEvent(ctkPluginFrameworkEvent)));framework->getPluginContext()->connectPluginListener(&eventListener, SLOT(slotPluginEvent(const ctkPluginEvent&)));framework->getPluginContext()->connectServiceListener(&eventListener, "slotServiceEvent");//QString dir = QCoreApplication::applicationDirPath();//dir += "/plugins/TestPlugin.dll";//QUrl url = QUrl::fromLocalFile(dir);QSharedPointer<ctkPlugin> plugin;
#if 1QDirIterator 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中的数据QHash<QString, 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;}}
#else#endifctkServiceReference ref = framework->getPluginContext()->getServiceReference<IPrintfService>();if (ref){IPrintfService* service = qobject_cast<IPrintfService*>(framework->getPluginContext()->getService(ref));if (service != nullptr){service->printf();}}//ctkPlugin::State sta = plugin->getState();//ctkPluginFrameworkLauncher::stop();//plugin->stop(); //plugin->uninstall();//sta = plugin->getState();CTKPlugin c;c.show();return a.exec();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/304944.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

usb_camera传输视频流编码的问题记录!

前言&#xff1a; 大家好&#xff0c;今天给大家分享的内容是&#xff0c;一个vip课程付费的朋友&#xff0c;在学习过程中遇到了一个usb采集的视频数据流&#xff0c;经过ffmpeg编码&#xff0c;出现了问题&#xff1a; 问题分析&#xff1a; 其实这个问题不难&#xff0c;关键…

git安装配置教程(小白保姆教程2024最新版)

目录 一、Git是什么?二、安装Git1.下载git2.安装git3.检测git 三、配置Git1.配置本地信息2.配置SSH1&#xff09;SSH与SSH Key是什么&#xff1f;2&#xff09;生成SSH Key3&#xff09;获取ssh key公钥内容&#xff08;id_rsa.pub&#xff09;4&#xff09;Github账号上添加公…

这段程序有点神奇,你能读懂么?

下面的程序在一个打开的文档中查找特定的字符串&#xff0c;这个字符串是“可以”&#xff0c;查找并仅保留最后的3次&#xff0c;抛弃其他的内容&#xff0c;请试运行一下&#xff0c;看看结果是否正确&#xff1f; from collections import deque def search(lines, pattern,…

【SpringBoot】配置swagger

pom.xml 安装插件 <dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId><version>3.0.0</version></dependency>创建swagger配置类 import org.springframework.context.annotation.…

如何使用Tomcat+cpolar搭建本地站点并发布到公网分享好友远程访问

文章目录 前言1.本地Tomcat网页搭建1.1 Tomcat安装1.2 配置环境变量1.3 环境配置1.4 Tomcat运行测试1.5 Cpolar安装和注册 2.本地网页发布2.1.Cpolar云端设置2.2 Cpolar本地设置 3.公网访问测试4.结语 前言 Tomcat作为一个轻量级的服务器拥有强大功能&#xff0c;由于其可以实…

如何使用Java和RabbitMQ实现延迟队列?

前言 今天我们使用Java和RabbitMQ实现消息队列的延迟功能。 前期准备&#xff0c;需要安装好docker、docker-compose的运行环境。 需要安装RabbitMQ的可以看下面这篇文章。 如何使用PHP和RabbitMQ实现消息队列&#xff1f;-CSDN博客 今天讲的是依赖RabbitMQ的延迟插件实现…

头歌-机器学习 第10次实验 逻辑回归

第1关&#xff1a;逻辑回归核心思想 任务描述 本关任务&#xff1a;根据本节课所学知识完成本关所设置的编程题。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 什么是逻辑回归&#xff1b; sigmoid函数。 什么是逻辑回归 当一看到“回归”这两个字&a…

【opencv】示例-falsecolor.cpp 使用OpenCV函数动态地对图像应用不同的色彩映射

该代码是一个使用OpenCV库实现的C程序&#xff0c;主要用来展示如何通过applyColorMap函数将色彩映射应用到一个灰度图像上&#xff0c;并提供一个滑动条来实时改变色彩映射的效果。此外&#xff0c;该程序还可以绘制包含不同形状的灰度图像&#xff0c;用作applyColorMap函数的…

QT 线程之movetothread

上文列举了qt中线程的几种方法&#xff0c;其中2种方法最为常见。 这两种方法都少不了QThread类&#xff0c;前者继承于QThread类&#xff0c;后者复合QThread类。 本文以实例的方式描述了movetothread&#xff08;&#xff09;这种线程的方法&#xff0c;将QObject的子类移动…

【MATLAB源码-第13期】基于matlab的4ASK的误码率BER和误符号率SER理论和实际对比仿真。

1、算法描述 "4ASK" 是一种数字调制技术&#xff0c;代表4级振幅移移键控&#xff08;4-Level Amplitude Shift Keying&#xff09;调制。它是一种数字通信中常用的调制方式之一&#xff0c;用于将数字信号转换为模拟信号以便传输&#xff0c;或者将模拟信号转换为数…

【ROS2笔记三】构建ROS2功能包

3.构建ROS2功能包 文章目录 3.构建ROS2功能包3.1ROS2中包的组成部分3.2创建ROS2功能包并编写节点3.2.1使用CMake创建功能包3.2.2编写cpp节点代码 3.3编译运行节点3.4使用面向对象的方式编写ROS2节点3.5使用RCLPY编写节点Reference 3.1ROS2中包的组成部分 ROS2可以使用CMake或者…

Linux从入门到精通 --- 3.用户、权限

文章目录 第三章&#xff1a;3.1 root用户3.1.1 su3.1.2 exit3.1.3 sudo 3.2 用户和用户组3.2.1 用户组管理创建用户组删除用户组 3.2.2 用户管理创建用户删除用户查看用户所属组修改用户所属组 3.2.3 getent一&#xff1a;二&#xff1a; 3.3 查看权限控制信息3.3.1 认知权限信…

计算机网络——WEB服务器编程实验

实验目的 1. 处理一个 http 请求 2. 接收并解析 http 请求 3. 从服务器文件系统中获得被请求的文件 4. 创建一个包括被请求的文件的 http 响应信息 5. 直接发送该信息到客户端 具体内容 一、C 程序来实现 web 服务器功能。 二、用 HTML 语言编写两个 HTML文件&#xff0c;并…

Access2019实现按关键字搜索查找所需要的数据的功能

问题&#xff1a;随着数据库中数据条目的不断增加&#xff0c;如何直观简单的根据某些字段中的关键词&#xff0c;查找到对应的数据条目就成为了必须&#xff0c;这里通过创建具有查询输入框的窗体&#xff0c;实现Access数据库内的搜索功能&#xff01;&#xff01; 零、实施…

【C语言】函数递归编程题

目录 题目一&#xff1a; 题目二&#xff1a; 题目三&#xff1a; 题目四&#xff1a; 总结 题目一&#xff1a; 题目&#xff1a;接受一个整型值&#xff08;无符号&#xff09;&#xff0c;按照顺序打印它的每一位。&#xff08;递归完成&#xff09; 列如&#xff1a; …

Harmony鸿蒙南向驱动开发-GPIO接口使用

功能简介 GPIO&#xff08;General-purpose input/output&#xff09;即通用型输入输出。通常&#xff0c;GPIO控制器通过分组的方式管理所有GPIO管脚&#xff0c;每组GPIO有一个或多个寄存器与之关联&#xff0c;通过读写寄存器完成对GPIO管脚的操作。 GPIO接口定义了操作GP…

Day80:服务攻防-中间件安全HW2023-WPS分析WeblogicJettyJenkinsCVE

目录 中间件-Jetty-CVE&信息泄漏 CVE-2021-34429(信息泄露) CVE-2021-28169(信息泄露) 中间件-Jenkins-CVE&RCE执行 cve_2017_1000353 CVE-2018-1000861 cve_2019_1003000 中间件-Weblogic-CVE&反序列化&RCE 应用金山WPS-HW2023-RCE&复现&上线…

windows ffmpeg7 通过rtsp拉取h265裸流

点击下边那个链接会转到github 下载完成后&#xff0c;添加include、lib到工程。 添加头文件&#xff1a; extern "C" { #include "libavcodec/avcodec.h" #include "libavformat/avformat.h" #include "libavformat/avio.h" #inclu…

Acrobat Pro DC 2021---PDF编辑与管理,打造高效PDF工作流程 含Mac+win

Acrobat Pro DC 2021包括全面的PDF编辑、OCR识别、多种输出格式转换以及强大的文件安全性保护。用户可轻松编辑、合并、转换PDF文件&#xff0c;同时支持将扫描文档转换为可编辑的PDF。可将PDF转换为Word、Excel、PowerPoint等格式&#xff0c;提高工作效率。 Mac电脑&#xf…

使用Docker部署开源项目FreeGPT35来免费调用ChatGPT3.5 API

Vercel部署FreeGPT35有严重限制&#xff0c;玩玩就好&#xff0c;真用还是得docker。 限制原因: Vercel的流式响应并不是一开始写流&#xff0c;客户端就能立刻收到响应流&#xff0c;而是先写到一个缓冲区&#xff0c;当流关闭才一股脑的流式响应回来(不是实时流) 因此导致: …