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 ,和 插件和描绘范例 .