Qt 为创建插件提供了 2 个 API:
例如:若想要编写自定义 QStyle 子类并让 Qt 应用程序动态加载它,将使用更高级 API。
由于更高级 API 建立在更低级 API 之上,因此有一些问题是两者公共的。
若想要提供用于 Qt Designer 的插件,见 Qt Designer 模块文档编制。
话题:
编写扩展 Qt 本身的插件是通过子类化适当插件基类、实现一些函数、及添加宏达成的。
有几个插件基类。默认情况下,派生插件存储在标准插件目录的子目录下。Qt 将找不到插件,若未将它们存储在适当目录下。
下表汇总了插件基类。某些类是私有的,因此未文档化。可以使用它们,但不承诺兼容更高 Qt 版本。
| 基类 | 目录名 | Qt 模块 | 键区分大小写 | 
|---|---|---|---|
| QAccessibleBridgePlugin | 
accessiblebridge
								 | Qt GUI | 区分大小写 | 
| QImageIOPlugin | 
imageformats
								 | Qt GUI | 区分大小写 | 
| QPictureFormatPlugin (obsolete) | 
pictureformats
								 | Qt GUI | 区分大小写 | 
| QAudioSystemPlugin | 
audio
								 | Qt Multimedia | 不区分大小写 | 
| QDeclarativeVideoBackendFactoryInterface | 
video/declarativevideobackend
								 | Qt Multimedia | 不区分大小写 | 
| QGstBufferPoolPlugin | 
video/bufferpool
								 | Qt Multimedia | 不区分大小写 | 
| QMediaPlaylistIOPlugin | 
playlistformats
								 | Qt Multimedia | 不区分大小写 | 
| QMediaResourcePolicyPlugin | 
resourcepolicy
								 | Qt Multimedia | 不区分大小写 | 
| QMediaServiceProviderPlugin | 
mediaservice
								 | Qt Multimedia | 不区分大小写 | 
| QSGVideoNodeFactoryPlugin | 
video/videonode
								 | Qt Multimedia | 不区分大小写 | 
| QBearerEnginePlugin | 
bearer
								 | Qt Network | 区分大小写 | 
| QPlatformInputContextPlugin | 
platforminputcontexts
								 | Qt Platform Abstraction | 不区分大小写 | 
| QPlatformIntegrationPlugin | 
platforms
								 | Qt Platform Abstraction | 不区分大小写 | 
| QPlatformThemePlugin | 
platformthemes
								 | Qt Platform Abstraction | 不区分大小写 | 
| QGeoPositionInfoSourceFactory | 
位置
								 | Qt Positioning | 区分大小写 | 
| QPlatformPrinterSupportPlugin | 
printsupport
								 | Qt Print Support | 不区分大小写 | 
| QSGContextPlugin | 
scenegraph
								 | Qt Quick | 区分大小写 | 
| QScriptExtensionPlugin | 
script
								 | Qt Script | 区分大小写 | 
| QSensorGesturePluginInterface | 
sensorgestures
								 | Qt Sensors | 区分大小写 | 
| QSensorPluginInterface | 
sensors
								 | Qt Sensors | 区分大小写 | 
| QSqlDriverPlugin | 
sqldrivers
								 | Qt SQL | 区分大小写 | 
| QIconEnginePlugin | 
iconengines
								 | Qt SVG | 不区分大小写 | 
| QAccessiblePlugin | 
accessible
								 | Qt Widgets | 区分大小写 | 
| QStylePlugin | 
styles
								 | Qt Widgets | 不区分大小写 | 
						若有新样式类称为
						
MyStyle
						
						想要将其用作插件,则需要按以下方式定义类 (
						
mystyleplugin.h
						
						):
					
class MyStylePlugin : public QStylePlugin { Q_OBJECT Q_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"));
某些插件类要求实现其它功能。见类文档编制,了解各插件类型必须重实现的虚函数的有关细节。
The 样式插件范例 shows如何实现插件以扩展 QStylePlugin 基类。
不只 Qt 本身,Qt 应用程序还可以被扩展透过插件。这要求应用程序检测并加载插件,使用 QPluginLoader 。在这种情况下,插件可以提供任意功能,不限于数据库驱动程序、图像格式、文本编解码器、样式及扩展 Qt 功能的其它类型插件。
透过插件使应用程序可扩展,涉及以下步骤:
编写插件涉及这些步骤:
.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_OBJECT Q_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); };
The 插件和描绘 范例文档编制会详细阐述此过程。另请参阅 创建自定义 Widget 为 Qt Designer 了解 Qt Designer 特定问题的有关信息。还可以查看 回显插件范例 ,这是有关如何实现扩展 Qt 应用程序插件的更通俗范例。请注意: QCoreApplication 必须已初始化,在可以加载插件之前。
Qt 应用程序自动知道哪些插件可用,因为插件存储在标准插件子目录下。应用程序不要求采用任何代码查找和加载插件,由于 Qt 会自动处理它们。
						在开发期间,插件目录为
						
QTDIR/plugins
						
						(在哪里
						
QTDIR
						
						是 Qt 的安装目录),各种类型的插件在该类型的子目录下,例如,
						
styles
						
						。若想要应用程序使用插件但又不想使用标准插件路径,让安装进程确定想要使用的插件路径并保存路径,例如,通过使用
						
							QSettings
						
						,供应用程序运行时读取。然后,应用程序可以调用
						
							QCoreApplication::addLibraryPath
						
						() 采用此路径,您的插件将可用于应用程序。注意,最后部分的路径 (例如,
						
styles
						
						) 无法更改。
					
						若想要插件可加载,一种途径是在应用程序下创建子目录,并将插件放置于该目录下。若分发 Qt 自带的任何插件 (其位于
						
plugins
						
						目录),必须拷贝其子目录在
						
plugins
						
						插件,位于应用程序根文件夹下 (即:不包括
						
plugins
						
						目录)。
					
有关部署的更多信息,见 部署 Qt 应用程序 and 部署插件 文档编制。
将插件包括在应用程序中的正常且最灵活方式,是将其编译成单独随附的动态库,并在运行时检测并加载。
可以将插件静态链接到应用程序。若构建静态版本的 Qt,这是包括 Qt 预定义插件的唯一选项。使用静态插件可使部署不易出错,但有缺点:无法添加插件功能,当不完整重新构建和重新分发应用程序时。
						要静态链接插件,需要将所需插件添加到构建使用
						
QTPLUGIN
						
						.
					
						在
						
.pro
						
						文件对于应用程序而言,需要以下条目:
					
QTPLUGIN     += qjpeg \
                qgif \
                qkrcodecs
					
					通常,qmake 将使用 Qt 模块所需的插件自动添加到 QTPLUGIN (见 QT ),而更专用的插件则需要手动添加。可以按类型覆盖自动添加的默认插件列表。例如,要链接 minimal 插件而不是默认 Qt 平台适配插件,使用:
QTPLUGIN.platforms = qminimal
若不想链接默认,也不想自动链接 minimal QPA 插件,使用:
QTPLUGIN.platforms = -
默认微调至最优开箱即用体验,但可能不必要膨胀应用程序。推荐通过 qmake 构建审查链接器命令行,并消除不必要插件。
为促使实际链接并实例化静态插件, Q_IMPORT_PLUGIN () 宏还需要在应用程序代码中,但这些是由 qmake 自动生成的,并已添加到应用程序工程中。
						若不想要添加到 QTPLUGIN 的所有插件被自动链接,移除
						
import_plugins
						
						从
						
CONFIG
						
						变量:
					
CONFIG -= import_plugins
创建自己的静态插件也是可能的,通过以下这些步骤:
CONFIG += static
							
							到插件的
							
.pro
							
							文件。
						
LIBS
							
							在
							
.pro
							
							文件。
						见 插件和描绘 范例和关联的 基本工具 插件,了解如何做到这的有关细节。
						
							注意:
						
						若不使用 qmake 构建插件,需要确保
						
QT_STATICPLUGIN
						
						预处理器宏有定义。
					
The 部署插件 文档涵盖采用应用程序部署插件和调试它们 (当出现问题时) 的过程。
另请参阅 QPluginLoader , QLibrary ,和 插件和描绘范例 .