Qt插件系统

概述

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

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

例如,如果您想编写一个自定义的QStyle子类并让Qt应用程序动态加载它,那么您将使用高级的API。
由于高级API构建在低级API之上,因此有些问题对两者都是通用的。
如果你想为Qt Designer提供插件,请参阅Qt Designer模块文档。

高级API:编写Qt扩展

通过继承适当的插件基类、实现一些函数和添加宏,可以编写扩展Qt本身的插件。

有几个插件基类。派生插件默认存储在标准插件目录的子目录中。如果插件没有存储在适当的目录中,Qt将无法找到它们。

下表总结了插件基类。有些类是私有的,因此没有在文档中记录。你可以使用它们,但不能保证与以后的Qt版本兼容。

Base ClassDirectory NameQt ModuleKey Case Sensitivity
QAccessibleBridgePluginaccessiblebridgeQt 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 WidgetsCase Insensitive

如果你有一个新的样式类MyStyle,你想让它作为一个插件可用,类需要定义如下(mystyleplugin.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()实现中使用小写版本的键;大多数其他插件是区分大小写的。)
此外,大多数插件都需要一个json文件(mystyleplugin.json),其中包含描述插件的元数据。对于样式插件,它只是包含一个可以由插件创建的样式列表:

{ "Keys": [ "mystyleplugin" ] }

json文件中需要提供的信息类型依赖于插件,请参阅类文档了解文件中需要包含的信息的详细信息。

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

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

一些插件类需要实现额外的函数。请参阅类文档了解必须为每种类型的插件重新实现的虚函数的详细信息。

样式插件示例展示了如何实现扩展QStylePlugin基类的插件。

低级API:扩展Qt应用程序

不仅Qt本身可以通过插件进行扩展,Qt应用程序也可以通过插件进行扩展。这要求应用程序使用QPluginLoader检测和加载插件。在这种情况下,插件可以提供任意功能,而且不限于数据库驱动、图像格式、文本编解码器、样式和其他扩展Qt功能的插件。

通过插件使应用程序具有可扩展性涉及以下步骤。

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

编写插件需要以下步骤。

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

例如,下面是一个接口类的定义:

class FilterInterface
{
public:virtual ~FilterInterface() {}virtual QStringList filters() const = 0;virtual QImage filterImage(const QString &filter, const QImage &image,QWidget *parent) = 0;
};

下面是实现该接口的插件类的定义:

#include <QObject>
#include <QtPlugin>
#include <QStringList>
#include <QImage>#include <plugandpaint/interfaces.h>class ExtraFiltersPlugin : public QObject, public FilterInterface
{Q_OBJECTQ_PLUGIN_METADATA(IID "org.qt-project.Qt.Examples.PlugAndPaint.FilterInterface" FILE "extrafilters.json")Q_INTERFACES(FilterInterface)public:QStringList filters() const;QImage filterImage(const QString &filter, const QImage &image,QWidget *parent);
};

Plug & Paint示例文档详细解释了这个过程。关于Qt Designer特有的问题的信息,请参见为Qt Designer创建自定义小部件。你也可以看一看Echo插件示例,这是一个关于如何实现扩展Qt应用程序的插件的更简单的示例。请注意,在加载插件之前,必须初始化QCoreApplication。

加载插件

Qt应用程序自动知道哪些插件可用,因为插件存储在标准的插件子目录中。因为这个应用程序不需要任何代码来查找和加载插件,因为Qt会自动处理它们。

在开发过程中,插件的目录是QTDIR/plugins(其中QTDIR是Qt安装的目录),每种类型的插件都有一个对应类型的子目录,例如styles。如果希望应用程序使用插件,而不想使用标准的插件路径,请让安装过程确定插件要使用的路径,并保存该路径,例如通过使用QSettings,以便应用程序在运行时读取。然后应用程序可以使用此路径调用QCoreApplication::addLibraryPath(),你的插件将对应用程序可用。注意,路径的最后一部分(例如styles)不能更改。

如果你希望插件是可加载的,那么一种方法是在应用程序下创建一个子目录,并将插件放在该目录中。如果发布任何Qt附带的插件(位于plugins目录下的那些),必须将插件所在的plugins子目录复制到应用程序根目录下(即不包含plugins目录)。

有关部署的更多信息,请参阅部署Qt应用程序和部署插件的文档。

静态插件

在应用程序中包含插件的常规和最灵活的方式是将其编译为单独发布的动态库,并在运行时检测和加载。

插件可以静态链接到应用程序中。如果构建的是静态版本的Qt,这是包含Qt预定义插件的唯一选择。使用静态插件使部署不那么容易出错,但有一个缺点,即在不完全重新构建和重新分发应用程序的情况下,无法添加来自插件的功能。

要静态链接插件,需要使用QTPLUGIN将所需的插件添加到构建中。

在你的应用程序的.pro文件中,你需要以下条目:

QTPLUGIN     += qjpeg \qgif \qkrcodecs

qmake会自动向QTPLUGIN中添加Qt模块通常需要的插件(参见Qt),而更专业的插件需要手动添加。每个类型都可以覆盖自动添加插件的默认列表。例如,要链接最小插件而不是默认的Qt平台适配插件,请使用:

QTPLUGIN.platforms = qminimal

如果你既不想默认的,也不想最小的QPA插件被自动链接,使用:

QTPLUGIN.platforms = -

默认值被调优为最佳的开箱即用体验,但可能会不必要地增加应用程序的体积。建议检查由qmake构建的链接器命令行,并删除不必要的插件

链接静态插件的详细信息

为了使静态插件真正被链接和实例化,应用程序代码中还需要Q_IMPORT_PLUGIN()宏,但这些宏是由qmake自动生成并添加到应用程序项目中的。

如果你不希望所有添加到QTPLUGIN的插件都自动链接,从CONFIG变量中删除import_plugins:

CONFIG -= import_plugins

创建静态插件

你也可以按照以下步骤创建自己的静态插件。

  • 将CONFIG += static添加到插件的.pro文件中。
  • 在应用程序中使用Q_IMPORT_PLUGIN()宏。
  • 如果插件提供qrc文件,请在应用程序中使用Q_INIT_RESOURCE()宏。
  • 在。pro文件中使用LIBS链接应用程序和插件库。

有关如何做到这一点的详细信息,请参阅Plug & Paint示例和相关的基本工具插件。

注意:如果您不使用qmake来构建插件,则需要确保定义了QT_STATICPLUGIN预处理器宏。

部署和调试插件

部署插件文档涵盖了使用应用程序部署插件并在出现问题时调试插件的过程。

See also QPluginLoader, QLibrary, and Plug & Paint Example.

How to Create Qt Plugins | Qt 5.15

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

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

相关文章

MS1112驱动开发(iio框架)

作者简介&#xff1a; 一个平凡而乐于分享的小比特&#xff0c;中南民族大学通信工程专业研究生在读&#xff0c;研究方向无线联邦学习 擅长领域&#xff1a;驱动开发&#xff0c;嵌入式软件开发&#xff0c;BSP开发 作者主页&#xff1a;一个平凡而乐于分享的小比特的个人主页…

Qt实现单例模式:Q_GLOBAL_STATIC和Q_GLOBAL_STATIC_WITH_ARGS

目录 1.引言 2.了解Q_GLOBAL_STATIC 3.了解Q_GLOBAL_STATIC_WITH_ARGS 4.实现原理 4.1.对象的创建 4.2.QGlobalStatic 4.3.宏定义实现 4.4.注意事项 5.总结 1.引言 设计模式之单例模式-CSDN博客 所谓的全局静态对象&#xff0c;大多是在单例类中所见&#xff0c;在之前…

工具链 之 Vite 开发服务器所有选项解析(三)

server 配置 // vite.config.js import { defineConfig } from vite // https://vitejs.dev/config/ export default defineConfig({ server: { origin: http://127.0.0.1:8080, //用于定义开发调试阶段生成资源的 originhost: 0.0.0.0, // 监听所有可用的网络接口 po…

idea插件开发之在项目右键添加菜单

写在前面 本文看下如何在右键列表中增加菜单。 正戏 首先创建一个Action&#xff0c;要显示的menu选择ProjectViewPopupMenu&#xff0c;如下&#xff1a; action public class CAction extends AnAction {Overridepublic void actionPerformed(AnActionEvent e) { // …

MATLAB算法实战应用案例精讲-【数模应用】偏相关分析(附MATLAB、python和R语言代码实现)

目录 前言 知识储备 相关性分析 一、实际应用 二、理论思想 三、操作过程 四、结果分析 算法原理 什么是偏相关 数学模型 (一) 偏相关系数r (二) 假设检验 偏相关分析过程 偏相关分析的SPSS实现 SPSS、EXCLE实现偏相关分析 STATA SPSSPRO 1、作用 2、输入输…

C#语言入门详解 --- 方法(含传值 输出 引用 数组)

方法 方法标准式 <Access Specifier> <Return Type> <Method Name>(Parameter List) { Method Body } 让我们逐一对每一个模块进行解释&#xff1a; Access Specifier&#xff1a;访问修饰符&#xff0c;这决定了接下来的主题的可见性&#xff0c;包含p…

使用python绘制三维直方图

使用python绘制三维直方图 三维直方图定义特点 效果代码 三维直方图 维直方图&#xff08;3D直方图&#xff09;是一种用于展示三维数据分布情况的图表。它扩展了二维直方图的概念&#xff0c;通过在三维空间中绘制柱体来表示数据在三个维度&#xff08;X、Y、Z&#xff09;上…

漏斗限流(leaky bucket)

漏斗限流(leaky bucket&#xff09; 介绍工作原理leaky bucket实现示例&#xff1a;搭配pool池pool.lua示例搭配示例 对象池&#xff08;pool&#xff09;结合漏斗限流&#xff08;leaky bucket&#xff09;的好处&#xff1a; 介绍 漏斗限流&#xff08;leaky bucket&#xff…

Ollama 配置多并发和多模型

ollama新版已经支持了并发和多模型同时运行了&#xff0c; 系统资源够的可以走起了 默认的ollama服务是不支持的&#xff0c; 需要自己进行调整&#xff0c; 调整的方式如下&#xff1a; Linux为例 通过调用 编辑 systemd 服务systemctleditollama.service 这将打开一个编辑器…

Changes Coming to NIAP Entropy Assessment Reports in 2025

“What do you say to a room full of DRBGs standing around you? Everyone, please be seeded.” -Quin, atsec tester When things change, it can help to approach that change with a light heart like this. Recently, NIAP announced that Entropy Assessment Rep…

结合gin框架在沙箱环境下实现电脑网站支付和当面支付

文章目录 配置支付宝开放平台编写代码测试电脑网站支付当面扫码支付 配置支付宝开放平台 支付宝开放平台 点击链接&#xff0c;扫码进入后&#xff0c;点击沙箱&#xff1a; 点击沙箱应用&#xff0c;可以看到APPID&#xff0c;接口加签方式选择系统默认密钥就行&#xff0…

基于Python的垃圾分类检测识别系统(Yolo4网络)【W8】

简介&#xff1a; 垃圾分类检测识别系统旨在利用深度学习和计算机视觉技术&#xff0c;实现对不同类别垃圾的自动识别和分类。应用环境包括Python编程语言、主流深度学习框架如TensorFlow或PyTorch&#xff0c;以及图像处理库OpenCV等&#xff0c;通过这些工具集成和优化模型&a…

第2天:项目结构与配置深入

第2天&#xff1a;项目结构与配置深入 目标 熟悉Django项目结构&#xff0c;配置基础设置。 任务概览 理解Django项目结构。配置settings.py。理解Django的URL配置。 详细步骤 理解Django项目结构 Django项目由一个或多个应用&#xff08;apps&#xff09;组成。每个应用…

js 实现图片纵向拼接并下载

js 使用canvas实现图片按照顺序拼接成纵向长图 /*** 图片拼接长图*/export default class ImageStitching {constructor(options) {this.imageUrls options.imageUrlsthis.images []this.imagesLoaded 0this.canvas nullthis.ctx nullthis.width options.width || 750th…

python判断一个数是不是偶数

在Python中&#xff0c;你可以使用模运算符 % 来判断一个数是否为偶数。模运算符会返回两个数相除的余数。如果一个数除以2的余数为0&#xff0c;那么这个数就是偶数。 以下是一个简单的Python函数&#xff0c;用于判断一个数是否为偶数&#xff1a; def is_even(n):return n…

成都爱尔林江院长建议近视防控从小做起,具体怎么做

预防近视应从小做起&#xff0c;知识储备多多益善。孩子如何做到近视防控&#xff1f; 成都爱尔眼科医院小儿眼科专家林江院长建议家长和孩子同时树立科学观念&#xff0c;让孩子拥有一个丰富多彩假期的同时强身健体也保护好眼睛。 不宅家、多户外 确保每天至少2个小时的户外…

【教程】SEO搜索优化怎么做?你必须知道的网站SEO诊断优化关键因素

在SEOer界流传着这样一句话,“内容为王,外链为皇,速度为后,内链为妃,代码为将,关键词为相,结构为城,更新为太子,工具为神兵”,我相信站长们对这条“黄金法则”一定都不陌生,其中“速度为后,工具为神兵”为土爹爹添加。毫不夸张地说,SEO(搜索引擎优化)就是大多数…

解锁5G新营销:视频短信的优势与全方位推广策略

随着5G时代的全面来临&#xff0c;企业的数字化转型步伐日益加快&#xff0c;视频短信作为新兴的数字营销工具&#xff0c;正逐步展现出其巨大的潜力。视频短信群发以其独特的形式和内容&#xff0c;将图片、文字、视频、声音融为一体&#xff0c;为用户带来全新的直观感受&…

线上盲盒小程序:前景展望

在移动互联网的浪潮下&#xff0c;线上盲盒小程序作为一种新兴的购物模式&#xff0c;具有广阔的发展前景和潜力。以下是对线上盲盒小程序未来前景的展望&#xff1a; 一、市场规模持续扩大 随着消费者需求的不断增长和市场竞争的加剧&#xff0c;线上盲盒小程序的市场规模将持…

【C#】scriptcs : 无法将“scriptcs”项识别为 cmdlet、函数、脚本文件或可运行程序的名

scriptcs : 无法将“scriptcs”项识别为 cmdlet、函数、脚本文件或可运行程序的名 最近在用vscode运行c#控制台程序是会出现上述的状况&#xff0c;几番周折之后找到了解决方法。 首先在电脑上安装scoop 然后运行powershell&#xff0c;分别输入 Set-ExecutionPolicy -Execu…