Qt 為創建插件提供瞭 2 個 API:
例如:若想要編寫自定義 QStyle 子類並讓 Qt 應用程序動態加載它,將使用更高級 API。
由於更高級 API 建立在更低級 API 之上,因此有一些問題是兩者公共的。
If you want to provide plugins for use with Qt Designer ,見 QtDesigner 模塊文檔編製。
話題:
編寫擴展 Qt 本身的插件是通過子類化適當插件基類、實現一些函數、及添加宏達成的。
There are several plugin base classes. Derived plugins are stored by default in sub-directories of the standard plugin directory. Qt will not find plugins if they are not stored in the right directory.
| 基類 | 目錄名 | 鍵區分大小寫 |
|---|---|---|
| QAccessibleBridgePlugin |
accessiblebridge
|
區分大小寫 |
| QAccessiblePlugin |
accessible
|
區分大小寫 |
| QDecorationPlugin |
decorations
|
不區分大小寫 |
| QFontEnginePlugin |
fontengines
|
不區分大小寫 |
| QIconEnginePlugin |
iconengines
|
不區分大小寫 |
| QImageIOPlugin |
imageformats
|
區分大小寫 |
| QInputContextPlugin |
inputmethods
|
區分大小寫 |
| QKbdDriverPlugin |
kbddrivers
|
不區分大小寫 |
| QMouseDriverPlugin |
mousedrivers
|
不區分大小寫 |
| QScreenDriverPlugin |
gfxdrivers
|
不區分大小寫 |
| QScriptExtensionPlugin |
script
|
區分大小寫 |
| QSqlDriverPlugin |
sqldrivers
|
區分大小寫 |
| QStylePlugin |
styles
|
不區分大小寫 |
| QTextCodecPlugin |
codecs
|
區分大小寫 |
Suppose that you have a new style class called
MyStyle
that you want to make available as a plugin. The required code is straightforward, here is the class definition (
mystyleplugin.h
):
class MyStylePlugin : public QStylePlugin { public: QStringList keys() const; QStyle *create(const QString &key); };
確保類實現位於
.cpp
file (including the class definition):
#include "mystyleplugin.h" QStringList MyStylePlugin::keys() const { return QStringList() << "MyStyle"; } QStyle *MyStylePlugin::create(const QString &key) { if (key.toLower() == "mystyle") return new MyStyle; return 0; } Q_EXPORT_PLUGIN2(pnp_mystyleplugin, MyStylePlugin)
(注意, QStylePlugin is case insensitive, and the lower-case version of the key is used in our create() 實現;其它大多數插件區分大小寫。)
對於數據庫驅動程序、圖像格式、文本編解碼器及大多數其它插件類型,明確創建對象不是必需的。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 <QStringList> #include <QImage> #include <plugandpaint/interfaces.h> class ExtraFiltersPlugin : public QObject, public FilterInterface { Q_OBJECT Q_INTERFACES(FilterInterface) public: QStringList filters() const; QImage filterImage(const QString &filter, const QImage &image, QWidget *parent); };
The 插件和描繪 範例文檔編製會詳細闡述此過程。另請參閱 創建自定義 Widget 為 Qt Designer for information about issues that are specific to Qt Designer . You can also take a look at the 迴顯插件範例 is a more trivial example on how to implement a plugin that extends Qt applications. Please note that a QCoreApplication 必須已初始化,在可以加載插件之前。
Qt 應用程序自動知道哪些插件可用,因為插件存儲在標準插件子目錄下。應用程序不要求采用任何代碼查找和加載插件,由於 Qt 會自動處理它們。
在開發期間,插件目錄為
QTDIR/plugins
(在哪裏
QTDIR
is the directory where Qt is installed), with each type of plugin in a subdirectory for that type, e.g.
styles
. If you want your applications to use plugins and you don't want to use the standard plugins path, have your installation process determine the path you want to use for the plugins, and save the path, e.g. using
QSettings
,供應用程序運行時讀取。然後,應用程序可以調用
QCoreApplication::addLibraryPath
() with this path and your plugins will be available to the application. Note that the final part of the path (e.g.,
styles
) 無法更改。
If you want the plugin to be loadable then one approach is to create a subdirectory under the application and place the plugin in that directory. If you distribute any of the plugins that come with Qt (the ones located in the
plugins
directory), you must copy the sub-directory under
plugins
插件,位於應用程序根文件夾下 (即:不包括
plugins
目錄)。
注意: In Symbian all binaries must be located in the directory \sys\bin, so each Qt plugin has a stub with the same basename as the plugin dll and suffix ".qtplugin" to make Qt extension plugins work similarly to other platforms. When trying to locate the plugin, Qt actually looks for the stub instead of the plugin binary. While plugin stub files have the suffix ".qtplugin", they can still be loaded also by specifying a filename with the normal library suffix ".dll" for QPluginLoader , so normally application developer doesn't need to care about the different suffix of the stub. Because of the way applications can be installed on ROM or various other drives in Symbian, Qt looks for the stub from the same directory on all available drives if it is not located in the given directory when loading a plugin.
有關部署的更多信息,見 部署 Qt 應用程序 and 部署插件 文檔編製。
將插件包括在應用程序中的正常且最靈活方式,是將其編譯成單獨隨附的動態庫,並在運行時檢測並加載。
Plugins can be linked statically against your application. If you build the static version of Qt, this is the only option for including Qt's predefined plugins. Using static plugins makes the deployment less error-prone, but has the disadvantage that no functionality from plugins can be added without a complete rebuild and redistribution of the application.
When compiled as a static library, Qt provides the following static plugins:
| Plugin name | 類型 | 描述 |
|---|---|---|
qtaccessiblecompatwidgets
|
可訪問性 | Accessibility for Qt 3 support widgets |
qtaccessiblewidgets
|
可訪問性 | Accessibility for Qt widgets |
qdecorationdefault
|
Decorations (Qt Extended) | Default style |
qdecorationwindows
|
Decorations (Qt Extended) | Windows style |
qgif
|
Image formats | GIF |
qjpeg
|
Image formats | JPEG |
qmng
|
Image formats | MNG |
qico
|
Image formats | ICO |
qsvg
|
Image formats | SVG |
qtiff
|
Image formats | TIFF |
qimsw_multi
|
Input methods (Qt Extended) | Input Method Switcher |
qwstslibmousehandler
|
Mouse drivers (Qt Extended) |
tslib
mouse
|
qgfxtransformed
|
Graphic drivers (Qt Extended) | Transformed screen |
qgfxvnc
|
Graphic drivers (Qt Extended) | VNC |
qscreenvfb
|
Graphic drivers (Qt Extended) | Virtual frame buffer |
qsqldb2
|
SQL driver | IBM DB2 |
qsqlibase
|
SQL driver | Borland InterBase |
qsqlite
|
SQL driver | SQLite version 3 |
qsqlite2
|
SQL driver | SQLite version 2 |
qsqlmysql
|
SQL driver | MySQL |
qsqloci
|
SQL driver | Oracle (OCI) |
qsqlodbc
|
SQL driver | Open Database Connectivity (ODBC) |
qsqlpsql
|
SQL driver | PostgreSQL |
qsqltds
|
SQL driver | Sybase Adaptive Server (TDS) |
qcncodecs
|
Text codecs | Simplified Chinese (People's Republic of China) |
qjpcodecs
|
Text codecs | 日語 |
qkrcodecs
|
Text codecs | 韓語 |
qtwcodecs
|
Text codecs | Traditional Chinese (Taiwan) |
To link statically against those plugins, you need to use the
Q_IMPORT_PLUGIN
() macro in your application and you need to add the required plugins to your build using
QTPLUGIN
. For example, in your
main.cpp
:
#include <QApplication> #include <QtPlugin> Q_IMPORT_PLUGIN(qjpeg) Q_IMPORT_PLUGIN(qgif) Q_IMPORT_PLUGIN(qkrcodecs) int main(int argc, char *argv[]) { QApplication app(argc, argv); ... return app.exec(); }
在
.pro
文件對於應用程序而言,需要以下條目:
QTPLUGIN += qjpeg \
qgif \
qkrcodecs
創建自己的靜態插件也是可能的,通過以下這些步驟:
CONFIG += static
到插件的
.pro
文件。
LIBS
在
.pro
文件。
見 插件和描繪 範例和關聯的 基本工具 插件,瞭解如何做到這的有關細節。
注意:
If you are not using qmake to build your application you need to make sure that the
QT_STATICPLUGIN
預處理器宏有定義。
The 部署插件 文檔涵蓋采用應用程序部署插件和調試它們 (當齣現問題時) 的過程。
另請參閱 QPluginLoader , QLibrary ,和 插件和描繪範例 .