Qt基于CTK Plugin Framework搭建插件框架--CTK服务工厂

news2025/1/19 3:05:25

一、前言

注册服务的时候能够用服务工厂来注册;

访问服务getServeice中的plugin参数是执行ctkPluginContext::getService(const ctkServiceReference&)的插件,从而工厂根据执行的不同插件名称返回不同的服务实现


服务工厂的作用

  • 在服务中可以知道是哪个其它插件在使用它;
  • 懒汉式使用服务,需要的时候才new;
  • 厂其它插件使用服务工厂和使用无服务工的服务,没有任何区别,代码都一样;
  • 可根据需要创建多种实现的服务,就是多种服务对应一个插件;

二、新建插件

在这里插入图片描述
插件结构

  • HelloService.h:接口类
  • HelloImpl.h:实现类
  • HelloActivator.h:激活类
  • ServiceFactory.h:服务工厂

工程文件:Hello.pro

QT += core
QT -= gui

TEMPLATE = lib
CONFIG += plugin
TARGET = Hello
DESTDIR = $$OUT_PWD/bin/plugins

include($$PWD/../CTK/CTK_dependency.pri)

HEADERS += \
    HelloActivator.h \
    HelloImpl.h \
    HelloService.h \
    ServiceFactory.h

RESOURCES += \
    qresource.qrc


接口类:HelloService.h

#ifndef HELLOSERVICE_H
#define HELLOSERVICE_H

#include <QtPlugin>

class HelloService
{
public:
    virtual ~HelloService() {}
    virtual void sayHello() = 0;
};

#define HelloService_iid "org.commontk.service.demos.HelloService"
Q_DECLARE_INTERFACE(HelloService, HelloService_iid)

#endif // HELLOSERVICE_H


实现类:HelloImpl.h

#ifndef HELLOIMPL_H
#define HELLOIMPL_H

#include "HelloService.h"
#include <QObject>
#include <QtDebug>

// HelloWorld
//---------------------------------------------------------
class HelloWorldImpl : public QObject, public HelloService
{
    Q_OBJECT
    Q_INTERFACES(HelloService)

public:
    void sayHello() Q_DECL_OVERRIDE {
        qDebug() << "Hello,World!";
    }
};

// HelloCTK
//---------------------------------------------------------
class HelloCTKImpl : public QObject, public HelloService
{
    Q_OBJECT
    Q_INTERFACES(HelloService)

public:
    void sayHello() Q_DECL_OVERRIDE {
        qDebug() << "Hello,CTK!";
    }
};

#endif // HELLOIMPL_H


激活类:HelloActivator.h

#ifndef HELLOACTIVATOR_H
#define HELLOACTIVATOR_H

#include <ctkPluginActivator.h>
#include <ctkPluginContext.h>
#include "HelloService.h"
#include "ServiceFactory.h"

class HelloActivator : public QObject, public ctkPluginActivator
{
    Q_OBJECT
    Q_INTERFACES(ctkPluginActivator)
    Q_PLUGIN_METADATA(IID "HELLO")

public:
    // 注册服务工厂
    void start(ctkPluginContext* context) {
        ServiceFactory *factory = new ServiceFactory();
        context->registerService<HelloService>(factory);
    }

    void stop(ctkPluginContext* context) {
        Q_UNUSED(context)
    }
};


#endif // HELLOACTIVATOR_H


服务工厂:ServiceFactory.h

#ifndef SERVICEFACTORY_H
#define SERVICEFACTORY_H

#include <ctkServiceFactory.h>
#include <ctkPluginConstants.h>
#include <ctkVersion.h>
#include "HelloImpl.h"

class ServiceFactory : public QObject, public ctkServiceFactory
{
    Q_OBJECT
    Q_INTERFACES(ctkServiceFactory)

public:
    ServiceFactory() : m_counter(0) {}

    // 创建服务对象
    QObject* getService(QSharedPointer<ctkPlugin> plugin, ctkServiceRegistration registration) Q_DECL_OVERRIDE {
        Q_UNUSED(registration)

        qDebug() << "Create object of HelloService for: " << plugin->getSymbolicName();
        m_counter++;
        qDebug() << "Number of plugins using service: " << m_counter;

        QHash<QString, QString> headers = plugin->getHeaders();
        ctkVersion version = ctkVersion::parseVersion(headers.value(ctkPluginConstants::PLUGIN_VERSION));
        QString name = headers.value(ctkPluginConstants::PLUGIN_NAME);

        QObject* hello = getHello(version);
        return hello;
    }

    // 释放服务对象
    void ungetService(QSharedPointer<ctkPlugin> plugin, ctkServiceRegistration registration, QObject* service) Q_DECL_OVERRIDE {
        Q_UNUSED(plugin)
        Q_UNUSED(registration)
        Q_UNUSED(service)

        qDebug() << "Release object of HelloService for: "  << plugin->getSymbolicName();
        m_counter--;
        qDebug() << "Number of plugins using service: "  << m_counter;
    }

private:
    // 根据不同的版本,获取不同的服务
    QObject* getHello(ctkVersion version) {
        if (version.toString().contains("alpha")) {
            return new HelloWorldImpl();
        } else {
            return new HelloCTKImpl();
        }
    }

private:
    int m_counter;  // 计数器
};

#endif // SERVICEFACTORY_H


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

达摩院2023十大科技趋势发布,生成式AI将进入应用爆发期

1月11日&#xff0c;达摩院2023十大科技趋势发布&#xff0c;生成式AI、Chiplet模块化设计封装、全新云计算体系架构等技术入选。达摩院认为&#xff0c;全球科技日趋显现出交叉融合发展的新态势&#xff0c;尤其在信息与通信技术&#xff08;ICT&#xff09;领域酝酿的新裂变&…

【关于Linux中----进程间通信方式之管道】

文章目录一、什么是管道二、匿名管道三、命名管道一、什么是管道 进程间通信主要目的为以下几点 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程 资源共享&#xff1a;多个进程之间共享同样的资源。 通知事件&#xff1a;一个进程需要向另一个或一组进程发送消息…

STL forward_list 模拟实现

forward_list 概述 forward_list 是 C 11 新增的容器&#xff0c;它的实现为单链表。 forward_list 是支持从容器中的任何位置快速插入和移除元素的容器&#xff0c;不支持快速随机访问。forward_list 和 list 的主要区别在于&#xff0c;前者的迭代器属于单向的 Forward Ite…

二分法讲解

目录 一、前言 二、二分法理论 1、引导&#xff1a;猜数游戏 2、理论背景&#xff1a;非线性方程的求根问题 1&#xff09;非线性方程的近似解 2&#xff09;搜索法和二分法 3、用二分的两个条件 4、二分法复杂度 三、整数二分 1、在单调递增序列中找 x 或者 x 的后继…

使用python-pptx创建PPT演示文档功能实践

python对PPT演示文档读写&#xff0c;是通过第三方库python-pptx实现的&#xff0c;python-pptx是用于创建和更新 PowerPoint&#xff08;.pptx&#xff09;文件的 Python 库。 关于PPT演示文档与幻灯片模板的内容不是本文的重点&#xff0c;在此略过。 1. PPT基本结构在pyth…

Sophus降维、升维与欧拉角、旋转向量的爱恨情仇

0. 简介 在面对二维与三维之间的转换时&#xff0c;我们常常会困惑该如何去转换&#xff0c;在G2O中存在有理想的坐标转换工具&#xff0c;但是在Sophus中却缺乏这样的手段。之前在Sophus处简要的介绍了一下SE(2)与SE(3)的转换&#xff0c;最近发现之前的文章这部分需要拿出来…

Leetcode:654. 最大二叉树(C++)

目录 问题描述&#xff1a; 实现代码与解析&#xff1a; 直接模拟&#xff08;递归)&#xff1a; 原理思路&#xff1a; 索引版本&#xff1a; 问题描述&#xff1a; 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&a…

Thymeleaf从入门到清晰使用

文章目录什么是thymeleaf&#xff1f;第一个Thymeleaf程序Thymeleaf详解配置常用标签最后什么是thymeleaf&#xff1f; 模板引擎&#xff1a; 前端交给我们的页面&#xff0c;是html页面&#xff0c;如果是以前开发&#xff0c;我们需要把他们转成jsp页面&#xff0c;jsp的好处…

ABB AC500 系列 PLC 与上位机iFix 的通讯配置

ABB PLC IP 及 MODBUS TCP/IP 协议设置 通过 IP config tool 配置设备 IP 在 软件中&#xff0c;有 3 种方式可以进入 IP config tool 的配置界面  双击 IP_settings&#xff0c;点击 IP config tool&#xff0c;即可进入 IP config tool 界面 点击菜单栏的 Tool→IP confi…

k8s 微服务spring boot JVM 监控

目录 1.前言 1.1 JVM监控方案 1.2 接入操作步骤 2. 服务开启actuator prometheus监控 2.1 示例参考添加依赖 2.2 配置prometheus监控 3 配置 prometheus 监控 4 配置jvm grafana dashboard 1.前言 服务 部署环境 监控 spring-demo k8s v1.22 Prometheus Operator …

进程相关概念

1、什么是程序&#xff0c;什么是进程&#xff0c;有什么区别 程序是静态的概念。例如&#xff1a;gcc xxx.c -o pro&#xff0c;磁盘中生成pro文件&#xff0c;叫做程序&#xff08;还未运行起来&#xff09; 进程是程序的一次运行活动&#xff0c;也就是程序跑起来了&#xf…

【Linux】信号机制(非实时信号)

目录 前言 一.信号的概念以及产生 1.什么是信号 2.信号分为两类 3.查看信号的命令 4.信号如何产生 1).通过软件产生 2).通过硬件产生 3).通过键盘组合键产生 二.信号的发送以及保存 1.信号如何发送 2.信号如何保存 1).概念 2).底层实现结构&&内核中的实现…

WampServer服务器设置控件

WampServer服务器设置控件 WampServer是一个web开发环境&#xff0c;是一个用于Windows操作系统的类似服务器的软件&#xff0c;由Romain Bourdon构建。该工具允许您开始构建web应用程序&#xff0c;并在Windows上使用Apache服务器2、PHP编程语言和MySQL数据库在本地网络上启动…

java 实现 springboot项目 使用socket推送消息,前端实时进行接收后端推送的消息

1 后端 1.1 添加依赖 在我们的springboot项目里面&#xff0c;添加依赖&#xff1b; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId><version>2.7.0</version>…

企业微信在职继承功能如何理解?怎么使用?

企业微信的在职继承功能就是企业管理员将在职员工的客户分配给其他在职员工跟进的一种方式&#xff0c;很方便&#xff0c;可以在工作出现变更时使用。 前言 企业微信之前的离职继承功能受到很多企业的青睐&#xff0c;企业能够将离职员工的客户分配给其他员工接手&#xff0c…

云天励飞在科创板获准注册:计划募资30亿元,陈宁为实际控制人

2023年1月10日&#xff0c;证监会发布公告&#xff0c;同意深圳云天励飞技术股份有限公司&#xff08;下称“云天励飞”&#xff09;首次公开发行股票注册。据贝多财经了解&#xff0c;云天励飞于2020年12月8日在科创板递交上市申请&#xff0c;2021年8月6日过会。 本次冲刺上市…

蓝队攻击的四个阶段(一)

蓝队的攻击是一项系统的工作&#xff0c;整个攻击过程是有章可循、科学合理的涵盖了从前期准备、攻击实施到靶标控制的各个步骤和环节。按照任务进度划分&#xff0c;一般可以将蓝队的工作分为4个阶段:准备工作、目标网情搜集、外网络向突破和内网横向拓展。第一阶段准备工作&a…

App开发提效法宝之插件技术

近年来技术革新频率越来越高&#xff0c;最近工作中经常有小伙伴问到插件技术的相关内容&#xff0c;今天就来跟大家系统的说清楚什么是插件技术以及它的好处。欢迎评论区交流哦&#xff01; 什么是插件技术&#xff1f; 插件技术指的是一种应用程序&#xff0c;遵循程序接口…

高温热水解预处理对厌氧消化期间污泥腐殖化的调控机制

期刊&#xff1a;Water Research 影响因子&#xff1a;9.13 发表时间&#xff1a;2022样本类型&#xff1a;污泥客户单位&#xff1a;同济大学凌恩生物客户同济大学发表在《Water Research》上的文章“The neglected effects of polysaccharide transformation on sludge humif…

振弦采集模块参数配置工具VMTool 的使用

振弦采集模块参数配置工具VMTool 的使用 准备工作 &#xff08; 1&#xff09; 将 VMXXX 模块的 UART_TTL、 RS232&#xff08; 或 RS485&#xff09; 接口与计算机的 COM 端口连接&#xff1b; &#xff08; 2&#xff09; 连接振弦传感器及温度传感器到 VMXXX 的对应接口&…