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

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

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

相关文章

Maven Repository使用

1.Maven Repository网站 https://mvnrepository.com/https://mvnrepository.com/ 2.查询需要的依赖 3.参考例子 <!-- https://mvnrepository.com/artifact/org.freeswitch.esl.client/org.freeswitch.esl.client --> <dependency> <groupId>org.freesw…

【k8s】资源管理命令-陈述式

一、资源管理介绍 1、资源管理概念 在kubernetes中&#xff0c;所有的内容都抽象为资源&#xff0c;用户需要通过操作资源来管理kubernetes。 //kubernetes的本质就是一个集群系统&#xff0c;用户可以在集群中部署各种服务&#xff0c;起始就是在kubernetes集群中运行一个个…

科技驱动教育!将名师智慧资产固定在系统中

文章目录 每日一句正能量前言未来教育教育趋势一、在线教育&#xff1a;打破时间和空间的限制二、混合式学习&#xff1a;结合线上和线下的优势三、项目式学习&#xff1a;以问题为导向&#xff0c;以项目为载体 科技驱动教育模式在线教育人工智能教育虚拟现实/增强现实教育游戏…

React事件处理

目录 前言 1. 添加事件处理函数 2. 传递参数 使用箭头函数 使用bind方法 3. 阻止默认行为和冒泡 阻止默认行为 阻止事件冒泡 4. 最佳实践 前言 React是一个流行的JavaScript库&#xff0c;用于构建用户界面。在React中&#xff0c;事件处理是非常重要的一部分&#xf…

“深入理解Nginx的负载均衡与动静分离“

目录 引言一、Nginx简介1. Nginx的基本概念2. Nginx的特点3. Nginx的安装配置 二、Nginx搭载负载均衡三、前端项目打包四、Nginx部署前后端分离项目&#xff0c;同时实现负载均衡和动静分离总结 引言 在现代互联网应用中&#xff0c;高性能和可扩展性是至关重要的。Nginx作为一…

吴恩达《机器学习》2-2->2-4:代价函数

一、代价函数的概念 代价函数是在监督学习中用于评估模型的性能和帮助选择最佳模型参数的重要工具。它表示了模型的预测输出与实际目标值之间的差距&#xff0c;即建模误差。代价函数的目标是找到使建模误差最小化的模型参数。 二、代价函数的理解 训练集数据&#xff1a;假设我…

操作系统 (1)

进程的概念 进程同步/进程互斥 进程互斥的软件实现 进程互斥的硬件实现 信号量机制 生产者消费者问题 以下wei8最终情况,不可调换位置,否则会发生死锁 预防死锁 避免死锁

警惕!当心AI诈骗!

本文参照材料有&#xff1a; 鄂尔多斯新闻公众号、澎湃新闻网、搜孤新闻、腾讯网等 AI换脸诈骗实例&#xff08;就发生在近期&#xff09; 事例一&#xff1a; 近期 “AI换脸”新型诈骗频发和你视频对话的可能不是本人&#xff01; 近日&#xff0c;东胜市民李女士遭遇了冒充…

Linux shell编程学习笔记18:while循环语句

上回我们研究和探讨了Linux shell编程中for 循环语句&#xff0c;与在C/C中一样&#xff0c;for 循环语句Linux shell编程中有很多灵活的用法。今天我们来研究和探讨while循环语句。 一、数字条件循环 我们继续以for循环语句中的例子&#xff0c;计算 从1到10与2的乘积 并输出…

浅述青犀AI算法人体攀爬行为检测的应用场景及解决方案

人体攀爬行为检测是指利用计算机视觉技术对人类攀爬物体的行为进行识别和分析。该技术主要依靠图像和视频数据进行分析&#xff0c;通过识别人类身体的各个部位&#xff0c;以及其在攀爬过程中的动作和姿态&#xff0c;实现对攀爬行为的检测和跟踪。该技术的场景应用比较广泛&a…

(2)STM32单片机上位机

使用VX小程序开发上位机&#xff0c; 样式如何创建&#xff1f; 在你所在页面 开辟空间 使用 view 在view 中 输入class 就是样式&#xff0c;在编辑样式的时候&#xff0c;如何寻找哪一块的样式 就是通过这个class寻找的 按钮使用switch

算法训练 第五周

一、多数元素 本题给了我们一个数组&#xff0c;要求我们找出这个数组中出现次数大于这个数组元素总量一半的那个元素&#xff0c;也可以理解为找出数组中出现次数最多的那个元素&#xff0c;本题的解决方法有很多&#xff0c;在此我们主要讨论三种解决思路。 1.Hash表 我们可…

Scala基本数据类型和运算符

1.数据类型 1.1 类型支持 Scala 拥有下表所示的数据类型&#xff0c;其中 Byte、Short、Int、Long 和 Char 类型统称为整数类型&#xff0c;整数类型加上 Float 和 Double 统称为数值类型。Scala 数值类型的取值范围和 Java 对应类型的取值范围相同。 数据类型 描述 Byte 8 …

百度竞价排名推广对比自然排名哪一个更具优势-华媒舍

在搜索引擎结论网页页面&#xff08;SERP&#xff09;中&#xff0c;我们经常会看到一些网站链接及其广告栏。这种连接一般分为两种类型&#xff1a;百度竞价推广排名推广与自然排名。究竟哪个更有优势&#xff1f;本文将对这几种排名形式进行科谱详细介绍。 什么叫百度竞价推广…

百度 | 文心一言也开始收费了

好久没用文心一言了 之前一直用ChatGPT的 今天打开文心一言一看&#xff0c;好家伙 出了文心大模型4.0&#xff0c;想体验一下来着 可惜是收费的 看下价格&#xff0c;没买 50块钱一个月&#xff0c;对比ChatGPT4来说&#xff0c;确实不算贵 毕竟gpt4一个月20美刀 &#xff0c;…

LEEDCODE 709转换成小写字母

class Solution { public:string toLowerCase(string s) {int len s.length();string a "";for(int i 0; i < len; i){if(s[i] > 65 && s[i] < 90){a (s[i] 32);}elsea s[i];}// cout<<a<<endl;return a;} };

Docker Compose部署Spug:实现内网穿透

文章目录 前言1. Docker安装Spug2 . 本地访问测试3. Linux 安装cpolar4. 配置Spug公网访问地址5. 公网远程访问Spug管理界面6. 固定Spug公网地址 前言 Spug 面向中小型企业设计的轻量级无 Agent 的自动化运维平台&#xff0c;整合了主机管理、主机批量执行、主机在线终端、文件…

Mac 安装使用NPM及常用命令

环境&#xff1a; Mac 工具&#xff1a; NPM 可通过官网查询一些模块相关 NPM Doc 通过官网文档了解更多的关于NPM的使用 安装 NPM是Node.js的包管理工具&#xff0c;可用于解决 Node.js在代码部署上的问题。 新版本的Node.js已经集成了NPM&#xff0c; 因此可通过下载 Nod…

安全架构的设计理论与实践

安全架构的设计理论与实践 安全架构概述 信息安全面临的威胁 安全架构的定义和范围 信息安全相关的国内外标准及组织 主要安全模型 状态机模型(BLP)模型 Bell-IaPadula模型 Biba模型 Clark-Wilson (CWM)模型 ChineseWall模型 系统安全体系架构规划框架 安全技术体系架构 信息系…

浏览器请求http地址,自动跳转成https

谷歌浏览器&#xff1a; 点击url地址左侧的锁&#xff0c;选择【网站设置】 点击【隐私和安全】&#xff0c;将【不安全内容】改为允许&#xff0c;然后刷新即可