当前位置: 首页 > news >正文

CTK框架(四): 插件编写

目录

1.生成插件

1.1.环境说明

1.2.服务类,纯虚类,提供接口

1.3.实现插件类,实现纯虚函数

1.4.激活插件,加入ctk框架的生命周期中

1.5.添加资源文件

1.6..pro文件

2.使用此插件

3.总结


1.生成插件

1.1.环境说明

编译ctk:Qt5.12.12+MSVC2017_64+Cmake

生成插件:Qt5.12.2+MSVC2017_64+qmake

1.2.服务类,纯虚类,提供接口

PluginAService.h

#ifndef PLUGINASERVICE_H
#define PLUGINASERVICE_H
#include <QtPlugin>class PluginAService
{
public:virtual ~PluginAService() {}virtual void A_Func() = 0;
};#define PluginAService_iid "org.commontk.service.demos.PluginAService"
Q_DECLARE_INTERFACE(PluginAService, PluginAService_iid)
//此宏将当前这个接口类声明为接口,后面的一长串就是这个接口的唯一标识。#endif // PLUGINASERVICE_H

1.3.实现插件类,实现纯虚函数

PluginAImpl.h

#ifndef PLUGINAIMPL_H
#define PLUGINAIMPL_H#include "PluginAService.h"
#include <QObject>class ctkPluginContext;class PluginAImpl : public QObject, public PluginAService
{Q_OBJECTQ_INTERFACES(PluginAService)/*此宏与Q_DECLARE_INTERFACE宏配合使用。Q_DECLARE_INTERFACE:声明一个接口类Q_INTERFACES:当一个类继承这个接口类,表明需要实现这个接口类*/public:PluginAImpl(ctkPluginContext* context);void A_Func() Q_DECL_OVERRIDE;
};#endif // PLUGINAIMPL_H

PluginAImpl.cpp

#include "PluginAImpl.h"
#include <QtDebug>PluginAImpl::PluginAImpl(ctkPluginContext* context)
{}void PluginAImpl::A_Func()
{qDebug() << "A_Func()";
}

1.4.激活插件,加入ctk框架的生命周期中

PluginAActivator.h

#ifndef PLUGINAACTIVATOR_H
#define PLUGINAACTIVATOR_H
#include <QObject>
#include "ctkPluginActivator.h"
#include "PluginAService.h"class PluginAActivator : public QObject, public ctkPluginActivator
{Q_OBJECTQ_INTERFACES(ctkPluginActivator)Q_PLUGIN_METADATA(IID "PLUGINA")//向Qt的插件框架声明,希望将xxx插件放入到框架中。public:void start(ctkPluginContext* context);void stop(ctkPluginContext* context);private:QSharedPointer<PluginAService> m_s;
};
#endif // PLUGINAACTIVATOR_H

PluginAActivator.cpp

#include "PluginAActivator.h"
#include "PluginAImpl.h"
#include <QDebug>void PluginAActivator::start(ctkPluginContext* context)
{PluginAImpl* pluginAImpl = new PluginAImpl(context);context->registerService<PluginAService>(pluginAImpl);m_s.reset(pluginAImpl);
}void PluginAActivator::stop(ctkPluginContext* context)
{Q_UNUSED(context)//Q_UNUSED,如果一个函数的有些参数没有用到、某些变量只声明不使用,但是又不想编译器、编辑器报警报,其他没有什么实际性作用
}

1.5.添加资源文件

资源名随便取,前缀为:PluginA/META_INF,文件名为:MANIFEST.MF

MANIFEST.MF内容:

注意:MANIFEST.MF的路径必须是这样,:/插件名/META-INF/MANIFEST.MF,否则系统找打不到此资源文件,此插件加载就会报异常。

MANIFEST.MF文件中有很多可填内容,在ctkPluginConstants.h中能找到相关宏定义

1.6..pro文件

include($$PWD/../../Plugins/Plugins.pri)QT       += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++11TARGET = PluginA# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0HEADERS += \PluginAActivator.h \PluginAImpl.h \PluginAService.hSOURCES += \PluginAActivator.cpp \PluginAImpl.cppRESOURCES += \resource.qrc

2.使用此插件

main.cpp

#include <QCoreApplication>
#include <ctkPluginFrameworkFactory.h>
#include <ctkPluginFramework.h>
#include <ctkPluginException.h>
#include <ctkPluginContext.h>
#include <QtDebug>
#include <QUrl>
#include "PluginAService.h"QString static firstPlugin_filePath = "D:/openCode/ctkcreator/bin/qmake/debug/plugins/PluginA.dll";int main(int argc, char *argv[])
{QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);QApplication a(argc, argv);//启动框架QString path = QCoreApplication::applicationDirPath() + "/linkplugins";ctkPluginFrameworkLauncher::addSearchPath(path, true);ctkProperties properties;properties.insert(ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN,     ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);ctkPluginFrameworkFactory fwFactory(properties);QSharedPointer<ctkPluginFramework> framework = fwFactory.getFramework();// 初始化并启动插件框架try {framework->init();framework->start();qDebug() << "CTK plugin framework start...";} catch (const ctkPluginException &e) {qDebug() << "CTK plugin framework init err: " << e.what();return -1;}// 获取插件服务的contexctkPluginContext* pluginContext = framework->getPluginContext();try {// 安装插件QSharedPointer<ctkPlugin> plugin = pluginContext->installPlugin(QUrl::fromLocalFile(firstPlugin_filePath));qDebug() << QString("Plugin[%1_%2] installed...").arg(plugin->getSymbolicName()).arg(plugin->getVersion().toString());// 启动插件plugin->start(ctkPlugin::START_TRANSIENT);qDebug() << "Plugin start...";} catch (const ctkPluginException &e) {qDebug() << QString("Failed install or run plugin: ") << e.what();return -2;}// 获取服务引用ctkServiceReference reference = pluginContext->getServiceReference<PluginAService>();if (reference) {// 获取指定 ctkServiceReference 引用的服务对象PluginAService* service = qobject_cast<PluginAService*>(pluginContext->getService(reference));if (service != Q_NULLPTR) {// 调用服务service->A_Func();}}return a.exec();
}

不出意外,在控制台会打印出"A_Func()"。

3.总结

        这就是在Qt和CTK中编写和使用插件的基本流程。CTK作为Qt的扩展,主要用于医疗应用开发,但插件的编写和加载机制仍然遵循Qt的标准做法。希望这能帮助你开始编写自己的CTK插件!

相关文章:

CTK框架(四): 插件编写

目录 1.生成插件 1.1.环境说明 1.2.服务类&#xff0c;纯虚类&#xff0c;提供接口 1.3.实现插件类&#xff0c;实现纯虚函数 1.4.激活插件&#xff0c;加入ctk框架的生命周期中 1.5.添加资源文件 1.6..pro文件 2.使用此插件 3.总结 1.生成插件 1.1.环境说明 编译ct…...

深入理解C代码中的条件编译

引言 条件编译是 C 编程中的一个重要特性&#xff0c;它允许开发人员根据不同的条件选择性地编译源代码的不同部分。这一特性对于编写跨平台的程序、优化代码性能或控制编译时资源消耗等方面非常重要。本文将深入探讨条件编译的工作原理、使用场景、高级应用以及注意事项&…...

Ubuntu16.04操作系统-内核优化

1. 概述 本文所用优化是生产环境中经过长期验证的内核优化策略&#xff0c;针对的服务器与POD主要用于高CPU、高内存、高IO的业务场景。 备注: OS: ubuntu16.04, 内核&#xff1a; 4.15.0-147-generic 主要涵盖以下内容优化&#xff1a; ulimit优化加强tcp参数其他内存参数 …...

Qt/C++编写的Onvif调试助手调试神器工具/支持云台控制/预置位设置等/有手机版本

一、功能特点 广播搜索设备&#xff0c;支持IPC和NVR&#xff0c;依次返回。可选择不同的网卡IP进行对应网段设备的搜索。依次获取Onvif地址、Media地址、Profile文件、Rtsp地址。可对指定的Profile获取视频流Rtsp地址&#xff0c;比如主码流地址、子码流地址。可对每个设备设…...

【原创】java+swing+mysql密码管理器系统设计与实现

个人主页&#xff1a;程序员杨工 个人简介&#xff1a;从事软件开发多年&#xff0c;前后端均有涉猎&#xff0c;具有丰富的开发经验 博客内容&#xff1a;全栈开发&#xff0c;分享Java、Python、Php、小程序、前后端、数据库经验和实战 文末有本人名片&#xff0c;希望和大家…...

JavaEE-HTTPHTTPS

目录 HTTP协议 一、概念 二、http协议格式 http请求报文 http响应报文 URL格式 三、认识方法 四、认识报头 HTTP响应中的信息 HTTPS协议 对称加密 非对称加密 中间人攻击 解决中间人攻击 HTTP协议 一、概念 HTTP (全称为 "超⽂本传输协议") 是⼀种应⽤…...

iLogtail 开源两周年:社区使用调查报告

作者&#xff1a;玄飏 iLogtail 作为阿里云开源的可观测数据采集器&#xff0c;以其高效、灵活和可扩展的特性&#xff0c;在可观测采集、处理与分析领域受到了广泛的关注与应用。在 iLogtail 两周年之际&#xff0c;我们对 iLogtail 开源社区进行了一次使用调研&#xff0c;旨…...

Ubuntu 比较两个文件夹

比较两个文件夹下的大量文件是否一致&#xff0c;可以通过以下几种方式完成&#xff1a; 1. 使用 diff 命令 diff 命令不仅可以比较文件&#xff0c;还能递归比较文件夹。可以使用 -r 选项来递归比较两个目录下的文件&#xff1a; diff -r /path/to/dir1 /path/to/dir2 如…...

两数之和--力扣1

两数之和 题目思路C代码 题目 思路 根据题目要求&#xff0c;元素不能重复且不需要排序&#xff0c;我们这里使用哈希表unordered_map。注意题目说了只对应一种答案。 所以我们在循环中&#xff0c;使用目标值减去当前循环的nums[i]&#xff0c;得到差值&#xff0c;如果我们…...

vue原理分析(三)new()创建Vue实例

今天我们来分析Vue实例的创建 代码如下&#xff1a; Vue.config.productionTip falsenew Vue({render: h > h(App),}).$mount(#app) Vue.config.productionTip false 这个配置成false&#xff0c;是阻止启动生产消息 new Vue({render: h > h(App),}).$mount(#app)…...

Spring MVC: 构建Web应用的强大框架

Spring MVC: 构建现代Web应用的强大框架 1. MVC设计模式简介 MVC (Model-View-Controller) 是一种广泛使用的软件设计模式,它将应用程序的逻辑分为三个相互关联的组件: Model (模型): 负责管理数据、业务逻辑和规则。View (视图): 负责用户界面的展示,将数据呈现给用户。Con…...

网络学习-eNSP配置NAT

NAT实现内网和外网互通 #给路由器接口设置IP地址模拟实验环境 <Huawei>system-view Enter system view, return user view with CtrlZ. [Huawei]undo info-center enable Info: Information center is disabled. [Huawei]interface gigabitethernet 0/0/0 [Huawei-Gigabi…...

动态规划-最长回文子串

题目描述 给你一个字符串 s&#xff0c;找到 s 中最长的 回文子串。 对于该题使用中心扩展法在某些情况下可以比动态规划方法更优&#xff0c;尤其是在处理较长字符串时。这是因为中心扩展法具有更好的空间复杂度&#xff0c;并且在实际应用中可能具有更快的运行速度&#xf…...

海康威视 嵌入式 面经 海康威视嵌入式软件 嵌入式硬件总结面试经验 面试题目汇总

标题海康威视 嵌入式 面经 海康威视嵌入式软件 嵌入式硬件总结面试经验 面试题目汇总 整理总结了海康威视嵌入式的面试题目&#xff01;&#xff0c;可以供大家面试参考 标题海康威视 嵌入式 面经 五月底投递&#xff0c;六月初面试&#xff0c;一场技术面&#xff0c;一场H…...

使用图论技巧——有遍数限制的最短路

给定一个 n个点 m 条边的有向图&#xff0c;图中可能存在重边和自环&#xff0c; 边权可能为负数。 请你求出从 11 号点到 n 号点的最多经过 k 条边的最短距离&#xff0c;如果无法从 1 号点走到 n 号点&#xff0c;输出 impossible。 注意&#xff1a;图中可能 存在负权回路…...

flume 使用 exec 采集容器日志,转储磁盘

flume 使用 exec 采集容器日志&#xff0c;转储磁盘 在该场景下&#xff0c;docker 服务为superset&#xff0c;flume 的sources 选择 exec &#xff0c; sinks选择 file roll 。 任务配置 具体配置文件如下&#xff1a; #simple.conf: A single-node Flume configuration#…...

459重复的子字符串

给定一个非空的字符串 s &#xff0c;检查是否可以通过由它的一个子串重复多次构成。 public repeatedSubstringPattern(String s){int n s.length();for(int i 1; i < n / 2; i){if(n % i ! 0) continue;// substring获取子字符串是左闭右开的String ss s.substring(0,…...

【HarmonyOS NEXT】实现截图功能

【HarmonyOS NEXT】实现截图功能 【需求】 实现&#xff1a;实现点击截图按钮&#xff0c;实现对页面/组件的截图 【步骤】 编写页面UI Entry Component struct Screenshot {BuildergetSnapContent() {Column() {Image().width(100%).objectFit(ImageFit.Auto).borderRadi…...

小皮面板webman ai项目本地启动教程

1.前置条件 下载小皮面板 下载后&#xff0c;双击安装&#xff0c;一路next&#xff08;下一步&#xff09;&#xff0c;无需更改配置。 2.安装必须软件 在小皮面板的软件管理页&#xff0c;安装编号①②③④下面四个软件。 3.启动本地服务 进入到小皮面板的首页&#x…...

从零实现诗词GPT大模型:实现多头自注意力

专栏规划: https://qibin.blog.csdn.net/article/details/137728228 在上一篇文章的最后,我们已经介绍了为什么要使用多头注意力了,本篇文章我们主要来实现多头自注意力,然后综合我们之前实现的FFN和TransformerBlock其实就差不多完成了整个GPT模型的实现了。 在开始实现之…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...