http://yanboo.ycool.com/post.2749491.html
(來(lái)自Qt文檔)
Qt有兩種與插件有關(guān)的API。一種用來(lái)擴(kuò)展Qt本身的功能,如自定義數(shù)據(jù)庫(kù)驅(qū)動(dòng),圖像格式,文本編解碼,自定義分格,等等,稱為Higher-Level API。另一種用于應(yīng)用程序的功能擴(kuò)展,稱為L(zhǎng)ower-Level API。前一種是建立在后一種的基礎(chǔ)之上的。這里討論的是后一種,即用來(lái)擴(kuò)展應(yīng)用程序的Lower-level API。
讓應(yīng)用程序支持插件擴(kuò)展的步驟:
1. 定義一個(gè)接口集(只有純虛函數(shù)的類),用來(lái)與插件交流。
2. 用宏Q_DECLARE_INTERFACE()將該接口告訴Qt元對(duì)象系統(tǒng)。
1 Q_DECLARE_INTERFACE(BrushInterface,"com.trolltech.PlugAndPaint.BrushInterface/1.0")
3. 應(yīng)用程序中用QPluginLoader來(lái)裝載插件。
4. 用宏qobject_cast()來(lái)確定一個(gè)插件是否實(shí)現(xiàn)了接口。
1 QObject *obj = new QTimer;
2 QTimer *timer = qobject_cast<QTimer *>(obj);
寫一個(gè)插件的步驟:
1. 聲明插件類,該類從QObject和該插件希望實(shí)現(xiàn)的接口繼承而來(lái)。
2. 用宏Q_INTERFACES()將該接口告訴Qt元對(duì)象系統(tǒng)。 1 class BasicToolsPlugin : public QObject,
2 public BrushInterface,
3 public ShapeInterface,
4 public FilterInterface
5 {
6 Q_OBJECT
7 Q_INTERFACES(BrushInterface ShapeInterface FilterInterface)
8 public:
9 ...
10 };
3. 用宏Q_EXPORT_PLUGIN2()導(dǎo)出插件。
1 Q_EXPORT_PLUGIN2 ( PluginName, ClassName )
4. 用適當(dāng)?shù)?pro文件構(gòu)建插件。
下面的代碼聲明了一個(gè)接口類:
1 class FilterInterface
2 {
3 public:
4 virtual ~FilterInterface() {}
5 virtual QStringList filters() const = 0;
6 virtual QImage filterImage(const QString &filter, const QImage &image, QWidget* parent)=0;
7 };
8
9 Q_DECLARE_INTERFACE(FilterInterface, "com.trolltech.PlugAndPaint.FilterInterface/1.0")
這里是實(shí)現(xiàn)該接口的插件類的定義:
1 #include <QObject>
2 #include <QStringList>
3 #include <QImage>
4
5 #include <plugandpaint/interfaces.h>
6
7 class ExtraFiltersPlugin : public QObject, public FilterInterface
8 {
9 Q_OBJECT
10 Q_INTERFACES(FilterInterface)
11
12 public:
13 QStringList filters() const;
14 QImage filterImage(const QString &filter, const QImage &image,
15 QWidget *parent);
16 };
示例 Plug & Paint 的文檔詳細(xì)解釋了這一過(guò)程。與Qt Designer有關(guān)的問(wèn)題請(qǐng)看Creating Custom Widgets for Qt Designer 。 Echo Plugin Example 是一個(gè)關(guān)于如何實(shí)現(xiàn)擴(kuò)展Qt應(yīng)用程序的詳細(xì)示例。
Loading and Verifying Plugins Dynamically
裝載插件時(shí)。Qt庫(kù)有一些健全檢查來(lái)確定插件能否被裝載和使用。這就可以同時(shí)安裝多個(gè)版本和Qt庫(kù)配置。
編譯插件來(lái)擴(kuò)展應(yīng)用程序時(shí),確保插件和應(yīng)用程序用同樣的配置這一點(diǎn)很重要。這意味著如果應(yīng)用程序是release模式編譯的,那么插件也要是release模式。
若將Qt配置為debug和release模式都編譯,但只在release模式下編譯應(yīng)用程序,就要確保你的插件也是在release模式下編譯的。缺省的,若Qt的debug編譯可用,插件就只在debug模式下編譯。要強(qiáng)制插件用release模式編譯,要在工程中添加:
CONFIG += release
這能確保插件兼容應(yīng)用程序中所用的庫(kù)版本。
The Build Key
裝載插件時(shí),Qt核對(duì)每一個(gè)插件的聯(lián)編關(guān)鍵字要和自己的匹配,以保證所裝載的是兼容的插件;任何不匹配的插件不會(huì)被裝載。
聯(lián)編關(guān)鍵字包含一下信息:
為了調(diào)試可能需要關(guān)閉聯(lián)編關(guān)鍵字校驗(yàn)功能,這可以通過(guò)將你運(yùn)行應(yīng)用程序的環(huán)境的環(huán)境變量QT_NO_PLUGIN_CHECK設(shè)置為非零來(lái)實(shí)現(xiàn)。
Static Plugins
插件能被靜態(tài)地鏈接到應(yīng)用程序。如果你創(chuàng)建了Qt的靜態(tài)版本,這僅僅是用來(lái)包含Qt的預(yù)定義插件的一個(gè)選項(xiàng)。
當(dāng)被作為靜態(tài)庫(kù)編譯時(shí),Qt提供下面這些靜態(tài)插件:
Plugin name | Type | Description |
---|
qtaccessiblecompatwidgets | Accessibility | Accessibility for Qt 3 support widgets |
qtaccessiblewidgets | Accessibility | Accessibility for Qt widgets |
qdecorationdefault | Decorations (Qtopia) | Default style |
qdecorationwindows | Decorations (Qtopia) | Windows style |
qgif | Image formats | GIF |
qjpeg | Image formats | JPEG |
qmng | Image formats | MNG |
qimsw_multi | Input methods (Qtopia) | Input Method Switcher |
qwstslibmousehandler | Mouse drivers (Qtopia) | tslib mouse |
qgfxtransformed | Graphic drivers (Qtopia) | Transformed screen |
qgfxvnc | Graphic drivers (Qtopia) | VNC |
qscreenvfb | Graphic drivers (Qtopia) | 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 | Japanese |
qkrcodecs | Text codecs | Korean |
qtwcodecs | Text codecs | Traditional Chinese (Taiwan) |
要靜態(tài)鏈接這些插件,你的應(yīng)用程序中要用到宏Q_IMPORT_PLUGIN() 并且要用QTPLUGIN將需要的插件添加到你的編譯中。例如,在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();
}
應(yīng)用程序的.pro 文件中要用下列條目:
QTPLUGIN += qjpeg \
qgif \
qkrcodecs
也可以創(chuàng)建自己的靜態(tài)庫(kù),步驟如下:
- 在插件的 .pro 文件中添加 CONFIG += static 。
- 應(yīng)用程序中用宏 Q_IMPORT_PLUGIN() 。
- 應(yīng)用程序的.pro 文件中用 LIBS 將靜態(tài)庫(kù)鏈接進(jìn)來(lái)。
參見示例 Plug & Paint 和相關(guān)的插件 Basic Tools 來(lái)獲得詳情。
The Plugin Cache
為了加速插件的裝載和確認(rèn),裝載插件時(shí)收集的信息被緩存到QSettings中。這包括插件是否被成功裝載的信息,以使后面的裝載操作不用再嘗試裝載無(wú)效的插件。但是,若一個(gè)插件的 last modified 時(shí)間戳被修改,插件的緩存條目是無(wú)效的并且插件會(huì)不管緩存條目中的值而被重新裝載,同時(shí)緩存條目本身也會(huì)被新的值替代。
這也意味著每一次插件或任何依賴資源(如共享庫(kù))被更新之后時(shí)間戳也必須被更新,因?yàn)橐蕾囐Y源可能影響一個(gè)插件裝載的結(jié)果。
有時(shí),開發(fā)插件時(shí),需要從插件緩存中移除條目。因?yàn)镼t用QSettings來(lái)管理插件緩存,插件的位置是依賴于平臺(tái)的;更多關(guān)于每一個(gè)平臺(tái)的信息請(qǐng)參看the QSettings documentation。
例如,Windows中這些條目存儲(chǔ)在注冊(cè)表中,每個(gè)插件的路徑是以下面兩個(gè)字串中的一個(gè)開始的:
HKEY_CURRENT_USER\Software\Trolltech\OrganizationDefaults\Qt Plugin Cache 4.2.debug
HKEY_CURRENT_USER\Software\Trolltech\OrganizationDefaults\Qt Plugin Cache 4.2.false
Debugging Plugins
有許多問(wèn)題可能影響到插件在應(yīng)用程序中的正常運(yùn)轉(zhuǎn)。 許多與插件和應(yīng)用程序的創(chuàng)建方法不同有關(guān), 通常發(fā)生在不同的創(chuàng)建系統(tǒng)和過(guò)程中。
下表描述的是開發(fā)者創(chuàng)建插件時(shí)遇到的問(wèn)題的常見原因:
Problem | Cause | Solution |
---|
應(yīng)用程序打開插件時(shí)插件裝載失敗且無(wú)提示。Qt Designer的Help|About Plugins對(duì)話框中顯示插件庫(kù),但這里沒(méi)有插件。 | 應(yīng)用程序和插件是在不同模式下創(chuàng)建的 | 使用相同的創(chuàng)建信息;或者在他們的工程文件中的CONFIG變量中添加debug_and_release來(lái)用debug和release兩種模式創(chuàng)建插件。 |
用有效的插件替代無(wú)效插件時(shí)裝載失敗 | 插件緩存中該插進(jìn)的條目顯示原來(lái)的插件不能被卸載,導(dǎo)致Qt忽略了替代 | 確保插件的時(shí)間戳被更新 或刪除插件緩存中的條目 |
也可以用QT_DEBUG_PLUGINS環(huán)境變量來(lái)從Qt中獲得嘗試去裝載的每一個(gè)插件的診斷信息。在應(yīng)用程序的運(yùn)行環(huán)境中把該變量的值設(shè)置為非零。
See also QPluginLoader, QLibrary, and Plug & Paint Example.
北京精神病醫(yī)院http://www.120ask-00.com/精神病醫(yī)院