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 ,和 插件和描繪範例 .