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

Qt 插件开发详解

1.简介

Qt插件是一种扩展机制,用于将应用程序的功能模块化,并且可以在运行时动态加载和卸载。Qt框架为插件提供了一套标准的接口和管理机制,使得插件的使用和集成变得简单和灵活,通过插件机制,可以将应用程序的功能划分为独立的可插拔的模块,使得应用程序更加可扩展和维护。

Qt插件系统具有以下特点:

  • 动态加载:Qt插件是在运行时动态加载的,允许在不重新编译或重新启动应用程序的情况下添加或移除插件。
  • 跨平台:Qt插件系统可以在不同的平台上运行,这意味着开发者可以使用相同的插件代码在Windows、macOS、Linux等多个操作系统上构建应用程序。
  • 松耦合:通过使用插件系统,应用程序可以以松耦合的方式使用插件。插件之间可以独立开发,编译和测试,然后在运行时动态加载到应用程序中。
  • 扩展性:Qt插件系统允许开发者根据应用程序的需求来设计和实现插件接口。这样,可以根据需要逐渐增加和扩展插件功能,而不会对应用程序的其他部分产生影响。

2.插件和动态库的区别

  • 功能和用途:动态库是一种包含可执行代码和数据的库,可以通过链接器将其与应用程序静态或动态地链接在一起。而Qt插件是一种特殊类型的动态库,用于扩展和增强Qt应用程序的功能。
  • API设计:动态库一般是一个完整的功能模块,可以直接调用其中的函数或使用其中的类。而Qt插件是基于插件接口或抽象类来设计的,通过继承插件接口并实现其纯虚函数来扩展插件的功能。
  • 动态加载:动态库通常需要在应用程序编译时与之链接,并在运行时加载。而Qt插件则是在运行时动态加载,可以根据需要添加或移除插件,而无需重新编译或启动应用程序。
  • 插件管理:Qt插件系统提供了更高级的插件管理功能,包括插件的自动发现、元信息的提取和注册、插件之间的依赖管理等。这使得使用和管理插件变得更加简单和灵活。

程序运行时需要动态库,否则运行不了,而插件不需要,在程序运行时动态加载。

3.如何创建插件

Qt提供了两个用于创建插件的API:

  • 一个高级API,用于编写Qt本身的扩展:自定义数据库驱动程序、图像格式、文本编解码器、自定义样式等。
  • 用于扩展Qt应用程序的低级API。

例如:如果您想编写一个自定义的QStyle子类并让Qt应用程序动态加载它,那么您可以使用更高级别的API。

编写一个扩展Qt本身的插件(高级API)是通过子类化适当的插件基类、实现一些函数和添加一个宏来实现的。

下表总结了插件基类,Qt的版本不同,插件会有些差别。 

Base ClassDirectory NameQt ModuleKey Case Sensitivity

QAccessibleBridgePlugin

accessiblebridgeQt GUICase Sensitive
QImageIOPluginimageformatsQt GUICase Sensitive
QPictureFormatPlugin (obsolete)pictureformatsQt GUICase Sensitive
QAudioSystemPluginaudioQt MultimediaCase Insensitive
QDeclarativeVideoBackendFactoryInterfacevideo/declarativevideobackendQt MultimediaCase Insensitive
QGstBufferPoolPluginvideo/bufferpoolQt MultimediaCase Insensitive
QMediaPlaylistIOPluginplaylistformatsQt MultimediaCase Insensitive
QMediaResourcePolicyPluginresourcepolicyQt MultimediaCase Insensitive
QMediaServiceProviderPluginmediaserviceQt MultimediaCase Insensitive
QSGVideoNodeFactoryPluginvideo/videonodeQt MultimediaCase Insensitive
QBearerEnginePluginbearerQt NetworkCase Sensitive
QPlatformInputContextPluginplatforminputcontextsQt Platform AbstractionCase Insensitive
QPlatformIntegrationPluginplatformsQt Platform AbstractionCase Insensitive
 
QPlatformThemePluginplatformthemesQt Platform AbstractionCase Insensitive
QGeoPositionInfoSourceFactorypositionQt PositioningCase Sensitive
QPlatformPrinterSupportPluginprintsupportQt Print SupportCase Insensitive
QSGContextPluginscenegraphQt QuickCase Sensitive
QScriptExtensionPluginscriptQt ScriptCase Sensitive
QSensorGesturePluginInterfacesensorgesturesQt SensorsCase Sensitive
QSensorPluginInterfacesensorsQt SensorsCase Sensitive
QSqlDriverPluginsqldriversQt SQLCase Sensitive
QIconEnginePluginiconenginesQt SVGCase Insensitive
QAccessiblePluginaccessibleQt WidgetsCase Sensitive
QStylePluginstylesQt Widgets

Case Insensitive

创建Qt本身的扩展:

如果你有一个名为MyStyle的新样式类,你想让它作为插件使用,那么这个类需要定义如下(mystyleplugin.h):

//.h
class MyStylePlugin : public QStylePlugin{Q_OBJECTQ_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "mystyleplugin.json")public:QStyle *create(const QString &key);};//.cpp#include "mystyleplugin.h"QStyle *MyStylePlugin::create(const QString &key){if (key.toLower() == "mystyle")return new MyStyle;return 0;}

QStylePlugin不区分大小写,在我们的create()实现中使用了小写版本;大多数其他插件都是区分大小写的。

对于数据库驱动程序、图像格式、文本编解码器和大多数其他插件类型,不需要显式的对象创建。Qt将根据需要查找并创建它们。style是个例外,因为您可能希望在代码中显式地设置样式。要应用样式,请使用以下代码。

 QApplication::setStyle(QStyleFactory::create("MyStyle"));

创建扩展Qt应用程序:

通过插件使应用程序可扩展包括以下步骤:

  • 定义一组用于与插件对话的接口(仅具有纯虚拟函数的类)。
  • 使用Q_DECLARE_INTERFACE()宏告诉Qt的元对象系统有关接口的信息。
  • 在应用程序中使用QPluginLoader来加载插件。
  • 使用qobject_cast()测试插件是否实现了给定的接口。

编写插件需要以下步骤:

  • 声明一个从QObject和插件想要提供的接口继承的插件类。
  • 使用Q_INTERFACES()宏告诉Qt的元对象系统有关接口的信息。
  • 使用Q_plugin_METADATA()宏导出插件。
  • 使用合适的.pro文件构建插件。

示例:

声明一个抽象接口类。

#ifndef COMPUTEINTERFACE_H
#define COMPUTEINTERFACE_H#include <QtPlugin>//定义接口
class ComputeInterface
{
public:virtual ~ComputeInterface() {}virtual int add(int a,int b) = 0;virtual int sub(int a,int b) = 0;
};#define ComputeInterface_iid "Test.Plugin.ComputeInterface"   // 唯一标识符QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(ComputeInterface, ComputeInterface_iid)
QT_END_NAMESPACE#endif // COMPUTEINTERFACE_H

定义实现该接口的插件类。

#ifndef COMPUTEPLUGIN_H
#define COMPUTEPLUGIN_H#include <QObject>
#include "../MainWidget/computeinterface.h"class ComputePlugin : public QObject, public ComputeInterface
{Q_OBJECTQ_PLUGIN_METADATA(IID ComputeInterface_iid)Q_INTERFACES(ComputeInterface)
public:explicit ComputePlugin(QObject *parent = nullptr);virtual int add(int a,int b);virtual int sub(int a,int b);
};#endif // COMPUTEPLUGIN_H#include "computeplugin.h"ComputePlugin::ComputePlugin(QObject *parent): QObject(parent)
{}int ComputePlugin::add(int a, int b)
{return a+b;
}int ComputePlugin::sub(int a, int b)
{return a-b;
}

加载插件:

//加载exe所在目录下  plugin文件夹的所有插件QDir path = QDir(qApp->applicationDirPath());path.cd("../../plugins");foreach (QFileInfo info, path.entryInfoList(QDir::Files | QDir::NoDotAndDotDot)){QPluginLoader pluginLoader(info.absoluteFilePath());QObject *plugin = pluginLoader.instance();if (plugin){ComputeInterface *app = qobject_cast<ComputeInterface*>(plugin);if (app){int ret = app->add(1,2);qDebug()<<"ret = "<<ret;}}}

 以下是工程目录结构:

4.完整工程

https://download.csdn.net/download/wzz953200463/88495546

相关文章:

Qt 插件开发详解

1.简介 Qt插件是一种扩展机制&#xff0c;用于将应用程序的功能模块化&#xff0c;并且可以在运行时动态加载和卸载。Qt框架为插件提供了一套标准的接口和管理机制&#xff0c;使得插件的使用和集成变得简单和灵活&#xff0c;通过插件机制&#xff0c;可以将应用程序的功能划…...

vue需求:实现签章/签字在页面上自由定位的功能(本质:元素在页面上的拖拽)

目录 第一章 效果展示 第二章 了解工具 2.1 draggable 2.1.1 了解draggable 2.1.2 draggable方法 2.1.3 利用例子理解方法 第三章 效果实现 3.1 实现思路 3.2 代码实现 3.2.1 涉及到的点 3.2.2 源代 第一章 效果展示 效果描述&#xff1a;通过点击左边栏的签名和…...

【深度学习基础】Pytorch框架CV开发(1)基础铺垫

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…...

uniapp原生插件之安卓热敏打印机打印插件

插件介绍 安卓热敏打印机打印插件&#xff0c;自动授权&#xff0c;打印机连接监听&#xff0c;打印文本&#xff0c;条形码&#xff0c;二维码&#xff0c;切纸&#xff0c;打印机状态&#xff0c;打印结果查询等 插件地址 安卓热敏打印机打印插件 - DCloud 插件市场 超级…...

巴菲特:卖比亚迪有助于资金配置

巴菲特表示&#xff0c;未来可能会有更多银行倒闭&#xff0c;但储户不必担心&#xff0c;他警告说&#xff0c;陷入困境的银行股不是价值投资&#xff0c;因为即使政府采取行动保护储户&#xff0c;股东的权益也会受到损失。他称&#xff0c;将加大对日本综合商社的投资&#…...

香港服务器有哪些特点

香港服务器具有以下特点&#xff1a; 速度快&#xff1a;香港服务器地理位置优越&#xff0c;与内地服务器相比&#xff0c;网络延迟更低&#xff0c;访问速度更快。 稳定性高&#xff1a;香港服务器位于全球重要的金融中心&#xff0c;网络环境稳定&#xff0c;服务器稳定性高…...

Leetcode76最小覆盖子串

思路&#xff1a;滑动窗口思想 1. 滑动窗口是什么&#xff1a;用一个滑动窗口为覆盖目标子串的字符串 2.怎么移动窗口&#xff1a;当不满足覆盖时右指针移动扩大范围&#xff0c;当覆盖了就移动左指针缩减范围直到再次不覆盖 3. 怎么判断是否覆盖&#xff1a;这里使用两个哈…...

GD32 单片机 硬件I2C死锁解决方法

死锁的复现方式 在I2C恢复函数下个断点&#xff08;检测到I2C多次超时之后&#xff0c;应该能跳转到I2C恢复函数&#xff09;使用镊子&#xff0c;将SCL与SDA短接&#xff0c;很快就能看到程序停到恢复函数的断点上&#xff0c;此时再执行恢复函数&#xff0c;看能否正常走出&…...

SPSS两相关样本检验

前言&#xff1a; 本专栏参考教材为《SPSS22.0从入门到精通》&#xff0c;由于软件版本原因&#xff0c;部分内容有所改变&#xff0c;为适应软件版本的变化&#xff0c;特此创作此专栏便于大家学习。本专栏使用软件为&#xff1a;SPSS25.0 本专栏所有的数据文件请点击此链接下…...

【vscode远程开发】使用内网穿透实现在公网环境下远程访问

文章目录 前言1、安装OpenSSH2、vscode配置ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu安装cpolar内网穿透4.2 创建隧道映射4.3 测试公网远程连接 5. 配置固定TCP端口地址5.1 保留一个固定TCP端口地址5.2 配置固定TCP端口地址5.3 测试固定公网地址远程 前言 远程…...

KaiwuDB 内核解析 - SQL 查询的生命周期

一、概述 KaiwuDB 内核解析系列共分上下两部分&#xff0c;本文是该系列的第一部分&#xff0c;主要涵盖了网络协议到 SQL 执行器&#xff0c;解释 KaiwuDB 如何执行 SQL 查询&#xff0c;包括系统各个组件的执行路径&#xff08;网络协议、SQL 会话管理、解析器、执行计划及优…...

2023.11.03 homework

小学4年级数学 1 2 3 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 19…...

ssm在线互助答疑系统-计算机毕设 附源码 20862

ssm在线互助答疑系统 摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&#…...

MySQL中如何书写update避免锁表

1. 什么是MySQL锁表&#xff1f; MySQL锁表是指在对某个数据表进行读写操作时&#xff0c;为了保证数据的一致性和完整性&#xff0c;系统会对该数据表进行锁定&#xff0c;防止其他用户对该表进行操作。 2. 为什么会出现锁表&#xff1f; 当多个用户同时对同一个数据表进行…...

Mysql库操作

一&#xff1a;库的操作 1&#xff1a;创建数据库 mysql> create database test1; Query OK, 1 row affected (0.00 sec)mysql> create database test2 charsetutf8;create database test2 character utf8;Query OK, 1 row affected (0.00 sec)mysql> create databa…...

C#中LINQtoSQL只能在.NetFramework下使用,不能在.net 下使用

目录 一、在net7.0下无法实现LINQtoSQL 1.VS上建立数据库连接 2.VS上创建LINQtoSQL 二、在.NetFramework4.8下成功实现LINQtoSQL 1.VS上建立数据库连接 2.VS上创建LINQtoSQL 三、结论 四、理由 本文是个人观点&#xff0c;因为我百般努力在.net7.0下无法实现LINQtoSQL的…...

Nacos 的底层实现原理 注册中心的两种调用方式

目录 1. Nacos 的底层实现原理 1.1 配置中心自动刷新实现原理 1.2 注册中心底层实现原理 2. Nacos 注册中心的两种调用方式 2.1 RestTemplate Spring Cloud LoadBalancer 的调用方式 2.2 使用 OpenFeign Spring Cloud LoadBalancer 1. Nacos 的底层实现原理 1.1 配置中心…...

视频编码格式和文件格式(多媒体容器格式)的关系

视频编码格式和文件格式是两个不同的概念。 视频编码格式指的是将视频信号转换为数字信号时所采用的压缩算法标准。它决定了如何将原始视频数据压缩为较小的文件大小&#xff0c;以及如何解码回原始视频数据。目前常见的视频编码格式有 H.264、H.265、VP9 等。 文件格式则是指…...

RHCSA --- 第二天

一、查看IP地址 [rootlocalhost ~] ip ad 对应四张网卡 第一张&#xff1a;环回网卡&#xff08;用于测试&#xff09; 第二张&#xff08;主要&#xff09;&#xff1a;以太网网卡&#xff08;ens160&#xff09; 2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP>…...

作为一个初学者,入门大模型其实没那么难

在生成式 AI 盛行的当下&#xff0c;你是否被这种技术所折服&#xff0c;例如输入一段简简单单的文字&#xff0c;转眼之间&#xff0c;一幅精美的图片&#xff0c;又或者是文笔流畅的文字就展现在你的面前。 相信很多人有这种想法&#xff0c;认为生成式 AI 深不可测&#xf…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

书籍“之“字形打印矩阵(8)0609

题目 给定一个矩阵matrix&#xff0c;按照"之"字形的方式打印这个矩阵&#xff0c;例如&#xff1a; 1 2 3 4 5 6 7 8 9 10 11 12 ”之“字形打印的结果为&#xff1a;1&#xff0c;…...

拟合问题处理

在机器学习中&#xff0c;核心任务通常围绕模型训练和性能提升展开&#xff0c;但你提到的 “优化训练数据解决过拟合” 和 “提升泛化性能解决欠拟合” 需要结合更准确的概念进行梳理。以下是对机器学习核心任务的系统复习和修正&#xff1a; 一、机器学习的核心任务框架 机…...

CppCon 2015 学习:REFLECTION TECHNIQUES IN C++

关于 Reflection&#xff08;反射&#xff09; 这个概念&#xff0c;总结一下&#xff1a; Reflection&#xff08;反射&#xff09;是什么&#xff1f; 反射是对类型的自我检查能力&#xff08;Introspection&#xff09; 可以查看类的成员变量、成员函数等信息。反射允许枚…...

【Java多线程从青铜到王者】单例设计模式(八)

wait和sleep的区别 我们的wait也是提供了一个还有超时时间的版本&#xff0c;sleep也是可以指定时间的&#xff0c;也就是说时间一到就会解除阻塞&#xff0c;继续执行 wait和sleep都能被提前唤醒(虽然时间还没有到也可以提前唤醒)&#xff0c;wait能被notify提前唤醒&#xf…...