QT外掛學習
轉自:http://blog.sina.com.cn/s/blog_63578f140100qr3v.html
外掛是什麼
-
注意:這兒暫時不考慮靜態外掛(潛意識中總覺得它根本就不算外掛)。
外掛是一個動態庫(共享庫)。動態庫是一個獨立的檔案中的獨立模組,可被多個程式訪問。
先看動態庫的兩種用法
1. 程式連結時指明動態庫
這時程式中包含相應的標頭檔案,編譯時指定標頭檔案路徑,對於qmake來說:
LIBS += -L/path1/path2/.../ -labcd INCLUDEPATH += /p1/p2/.../
這樣一來,程式啟動時會自動載入需要的連結庫。
2. 程式中動態載入動態庫
執行過程中找到來查詢某個動態庫,載入並解析出其中的某個函式。 Qt提供了QLibrary這個類來封裝各個平臺下的差異。
外掛是提供特定介面的動態庫
- 它是動態庫
- 它需要一個或幾個特定的介面(這樣程式才能感知它)
- 它採用第二種載入方式
- Qt 為外掛提供了 QPluginLoader,比通用 QLibrary 好用
Qt外掛位置
動態載入,那麼程式怎麼知道去哪兒載入外掛呢?
很多人抱怨,裝有Qt的機器上一切正常,釋出後,jpeg等格式圖片看不成,資料庫無法連線,漢字亂碼...
其實答案很簡單:
QCoreApplication 的 libraryPaths() 中有一些路徑,比如:
- $QTDIR/plugins
- 可執行程式所在資料夾
然後程式啟動後,會去這些路徑下的下列子目錄
-
imagesformats
中 找圖片外掛
sqldrivers
中 找資料庫驅動外掛
codecs
中 找字元的編解碼外掛
...
這就是為什麼:將 jpeg4.dll 放到可執行程式所在資料夾的 imagesformats 中即可解決問題的原因。
除此之外,要設定外掛路徑,我們還可以修改:
QCoreApplication::libraryPaths() |
通過 addLibraryPath() |
QLibraryInfo::location(QLibraryInfo::PluginsPath) |
通過 qt.conf 檔案 |
QT_PLUGIN_PATH |
環境變數 |
Manual 中對此有詳細介紹。
外掛API
Qt 提供了兩個層次的Api
Higher-level |
用於擴充套件Qt自身的工程,比如前述的圖片外掛、編解碼外掛等等 |
Lower-level |
用於擴充套件 應用程式的功能,比如 QtCreator 本身用了非常多的專有外掛 |
higher-level
這部分,外掛本身的api很簡單,困難在功能實現上。比如實現一個 style 外掛:
- 派生 QStyle 或它的子類,實現自己的 Style 類(難點)
- 派生 QStylePlugin,實現外掛,在它內部建立 Style 的物件
這兩個都沒什麼好說的,只是一個巨集特別關鍵:
Q_EXPORT_PLUGIN2(PluginName, ClassName)
看它的原始碼,也是一堆巨集,貼出來也不好看
# define Q_EXPORT_PLUGIN2(PLUGIN, PLUGINCLASS) \
Q_PLUGIN_VERIFICATION_DATA \
Q_EXTERN_C Q_DECL_EXPORT \
const char * Q_STANDARD_CALL qt_plugin_query_verification_data() \
{ return qt_plugin_verification_data; } \
Q_EXTERN_C Q_DECL_EXPORT QT_PREPEND_NAMESPACE(QObject) * Q_STANDARD_CALL qt_plugin_instance() \
Q_PLUGIN_INSTANCE(PLUGINCLASS)
展開看一下:
static const char qt_plugin_verification_data[] = \
"pattern=QT_PLUGIN_VERIFICATION_DATA\n" \
"version=4.7.0\ndebug=false\nbuildkey=xxx";
extern "C" Q_DECL_EXPORT const char * qt_plugin_query_verification_data()
{
return qt_plugin_verification_data;
}
extern "C" Q_DECL_EXPORT qt_plugin_instance()
{
static QPointer<QObject> _instance;
if (!_instance)
_instance = new ClassName;
return _instance;
}
這樣一來舒服多了,匯出了兩個函式:
- 一個返回值是一個長長的字串,用來校驗差價和程式所用Qt版本什麼的是否匹配
- 另一個返回的是外掛類的物件,這樣通過該函式就可以使用外掛了。
lower-level
這一部分和本文其他部分關係不是太緊密,而且內容可能比較多,還是單獨出來準備"外掛學習二"吧。
- 不像圖片外掛、資料庫外掛等,Qt為他們提供了現成的介面。這兒我們必須實現自己的介面(別人也不清楚我們的需求,對吧)
靜態外掛
- 這個東西怎麼說呢,儘管靜態編譯過Qt,但基本沒用過。所以在這靜態外掛上面應該更沒有什麼發言權。
- 熟悉Qt靜態編譯的,應該對此更熟一些,因為這是外掛都是靜態的。
靜態外掛使用
這時它是一個靜態庫。靜態庫如何使用?不用多說了,肯定直接連結到程式中。於是我們需要:
- 包含標頭檔案
- 指定連結庫
對與Qt提供的 higher-level 外掛,比如圖片外掛 jpeg,這意味著:
程式碼中,(使用巨集,也就是使動態編譯時它不起作用)
-
#include<QtPlugin>
-
Q_IMPORT_PLUGIN(qjpeg)
pro檔案內,(指定要連結的庫)
- QTPLUGIN += qjpeg
靜態外掛用到的巨集
當靜態編譯時,外掛中的巨集
Q_EXPORT_PLUGIN2(PLUGINNAME, ClassName)
展開為
qt_plugin_instance_PLUGINNAME() { static QPointer<QObject> _instance; if (!_instance) _instance = new ClassName; return _instance; }
同時,工程中的巨集
Q_IMPORT_PLUGIN(PluginName)
展開為:
QObject *qt_plugin_instance_PLUGINNAME(); class StaticPLUGINNAMEPluginInstance { public: StaticPLUGINNAMEPluginInstance() { qRegisterStaticPluginInstanceFunction(qt_plugin_instance_PLUGINNAME); } }; static StaticPLUGINNAMEPluginInstance staticPLUGINNAMEInstance;
這也很容易理解,Q_EXPORT_PLUGIN2(PLUGINNAME, ClassName) 中的第一個引數做什麼用了。
參考
相關文章
- Qt學習--Qt Plugin建立及呼叫2(外掛管理器)QTPlugin
- Qt入門(11)——Qt外掛QT
- cmake構建Qt外掛QT
- Qt Creator 原始碼學習筆記04,多外掛實現原理分析QT原始碼筆記
- 360外掛化方案RePlugin學習筆記-外接外掛Plugin筆記
- OctoberCMS 外掛學習 側邊欄
- octobercms 外掛學習 驗證碼
- IDEA外掛開發學習Idea
- Cordova學習--iOS自定義外掛iOS
- RePlugin外掛化框架的學習Plugin框架
- bootstrap學習筆記 外掛概述boot筆記
- 【django學習-24】自定義外掛Django
- Gradle外掛學習筆記(一)Gradle筆記
- Gradle外掛學習筆記(四)Gradle筆記
- Bootstrap外掛modal原始碼的學習boot原始碼
- bootstrap外掛學習-bootstrap.modal.jsbootJS
- Flutter學習指南:封裝 API 外掛Flutter封裝API
- Gradle外掛學習筆記(三)Gradle筆記
- Gradle外掛學習筆記(二)Gradle筆記
- Qt學習2QT
- Egg 學習筆記 - 外掛的使用筆記
- 元件化與外掛化的學習(一)元件化
- bootstrap 學習筆記 輪播(Carousel)外掛boot筆記
- Qt自定義外掛plugin的開發和呼叫QTPlugin
- Qt學習之XMLQTXML
- Qt學習之路2QT
- 【轉】qt-vs-addin:Qt4和Qt5之VS外掛如何共存與使用QT
- Flutter外掛學習之Native通訊詳解Flutter
- 學習外掛 -------- 成長過程(經典推薦)
- Qt 事件機制 學習QT事件
- 基於jquery的外掛turn.js學習筆記jQueryJS筆記
- 新手要正確看待外掛學習與資料分析
- 學習外掛編寫開發所必備技術
- jquery複習之路---常用外掛jQuery
- QT學習筆記4(動畫)QT筆記動畫
- QT5學習 QFileSystemModelQT
- QT學習記錄總結QT
- QT 學習錯誤總結QT