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 | 區分大小寫 |
| QBearerEnginePlugin |
bearer
|
Qt Network | 區分大小寫 |
| QPlatformInputContextPlugin |
platforminputcontexts
|
Qt Platform Abstraction | 不區分大小寫 |
| QPlatformIntegrationPlugin |
platforms
|
Qt Platform Abstraction | 不區分大小寫 |
| QPlatformThemePlugin |
platformthemes
|
Qt Platform Abstraction | 不區分大小寫 |
| QPlatformPrinterSupportPlugin |
printsupport
|
Qt Print Support | 不區分大小寫 |
| QSGContextPlugin |
scenegraph
|
Qt Quick | 區分大小寫 |
| 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 () implementation; most other plugins are case sensitive.)
此外,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 預定義插件的唯一選項。使用靜態插件可使部署不易齣錯,但有缺點:無法添加插件功能,當不完整重新構建和重新分發應用程序時。
CMake and qmake automatically add the plugins that are typically needed by the Qt modules used, while more specialized plugins need to be added manually. The default list of automatically added plugins can be overridden per type.
The defaults are tuned towards an optimal out-of-the-box experience, but may unnecessarily bloat the application. It is recommended to inspect the linker command line and eliminate unnecessary plugins.
為促使實際鏈接並實例化靜態插件, Q_IMPORT_PLUGIN () macros are also needed in application code, but those are automatically generated by the build system and added to your application project.
To statically link plugins in a CMake project, you need to call the qt_import_plugins 命令。
For example, the Linux
libinput
plugin is not imported by default. The following command imports it:
qt_import_plugins(myapp INCLUDE Qt::QLibInputPlugin)
To link the minimal platform integration plugin instead of the default Qt platform adaptation plugin, use:
qt_import_plugins(myapp
INCLUDE_BY_TYPE platforms Qt::MinimalIntegrationPlugin
)
Another typical use case is to link only a certain set of
imageformats
plugins:
qt_import_plugins(myapp
INCLUDE_BY_TYPE imageformats Qt::QJpegPlugin Qt::QGifPlugin
)
If you want to prevent the linking of any
imageformats
plugin, use:
qt_import_plugins(myapp
EXCLUDE_BY_TYPE imageformats
)
If you want to turn off the addition of any default plugin, use the
NO_DEFAULT
option of
qt_import_plugins
.
In a qmake project, you need to add the required plugins to your build using
QTPLUGIN
:
QTPLUGIN += qlibinputplugin
For example, to link the minimal plugin instead of the default Qt platform adaptation plugin, use:
QTPLUGIN.platforms = qminimal
若不想鏈接默認,也不想自動鏈接 minimal QPA 插件,使用:
QTPLUGIN.platforms = -
若不想要添加到 QTPLUGIN 的所有插件被自動鏈接,移除
import_plugins
從
CONFIG
變量:
CONFIG -= import_plugins
創建自己的靜態插件也是可能的,通過以下這些步驟:
STATIC
選項到
qt_add_plugin
command in your
CMakeLists.txt
. For a qmake project, add
CONFIG += static
到插件的
.pro
文件。
CMakeLists.txt
or
LIBS
在您的
.pro
文件。
見 插件和描繪 範例和關聯的 基本工具 插件,瞭解如何做到這的有關細節。
注意:
If you are not using CMake or qmake to build your plugin, you need to make sure that the
QT_STATICPLUGIN
預處理器宏有定義。
The 部署插件 文檔涵蓋采用應用程序部署插件和調試它們 (當齣現問題時) 的過程。
另請參閱 QPluginLoader , QLibrary ,和 插件和描繪範例 .