全網最詳細的Qt外掛搭建及載入步驟
在開展新內容前,先簡單回顧下上篇文章的內容。
上次我們是直接在Qt 自帶的例子基礎上做的修改,直接執行。我們的外掛需要繼承Qt 的Style外掛,之後重新實現自己想要實現的部分。在主程式中直接透過QApplication::setStyle進行呼叫。
下面開展我們本次的內容,官方文件說明
透過外掛不僅可以擴充套件Qt本身,而且可以擴充套件Qt應用程式。 這要求應用程式使用QPluginLoader檢測和載入外掛。 在這種情況下,外掛可以提供任意功能,並且不僅限於資料庫驅動程式,影象格式,文字編解碼器,樣式以及擴充套件Qt功能的其他型別的外掛。
透過外掛使應用程式可擴充套件涉及以下步驟:
①定義一組用於與外掛對話的介面(僅具有純虛擬函式的類)。
②使用Q_DECLARE_INTERFACE ()宏向Qt的元物件系統宣告該介面。
③在應用程式中使用QPluginLoader載入外掛。
④使用qobject_cast()測試外掛是否實現了給定的介面。
編寫一個外掛的步驟:
①宣告一個外掛類,該類繼承自QObject和該外掛要提供的介面。
②使用Q_INTERFACES ()宏告訴Qt的元物件系統有關介面的資訊。
③使用Q_PLUGIN_METADATA ()宏匯出外掛。
④使用合適的。pro檔案構建外掛。
上面的步驟看不大懂?沒關係,下面我們透過程式來逐步分解上面的步驟
建立子工程Qt應用程式
在Qt新建工程時,選擇建立子工程,如下圖。
按照提示完成子工程的建立,我的工程名稱是MyFirstPlugin
建立完成後工程是空的,選中工程後滑鼠右鍵,【New SubProject。。。】,如圖。之後新增的子工程就像平時建立帶有UI的工程一樣,我選擇的是繼承QWidget。
此時編譯執行的話會顯示一個為空的QWidget窗體。建立成功後大概向下面的樣子
透過外掛使應用程式可以被擴充套件
【應用程式擴充套件外掛步驟】
①編寫僅具有純虛擬函式的類
選中資料夾Headers後右鍵,選擇【Add New。。。】,選擇【C++ Header File】,我的名稱是 abstractinterface。h。由於我想建立的外掛是帶有UI的,所以型別是QWidget 。
#include
class QWidget;
class AbstractInterface
{
public:
virtual ~AbstractInterface() {}
virtual QWidget *createPluginWidget(QWidget *parent) = 0;
};
【應用程式擴充套件外掛步驟】
②使用Q_DECLARE_INTERFACE ()宏向Qt的元物件系統宣告該介面。
裡面字串內容是宣告一個獨一無二的屬於你的iid,我的是“歡迎關注公眾號”。
#define AbstractInterface_iid “Welcome to pay attention to the public number”
Q_DECLARE_INTERFACE(AbstractInterface, AbstractInterface_iid)
此時透過外掛使應用程式可以被擴充套件的前兩步就完成了,後面兩步之後在宿主程式中載入外掛時再介紹。此時你的工程看起來是這個樣子:
再新增一個子工程用於編寫外掛
①再次新增一個子工程
選中工程【MyFirstPlugin】後滑鼠右鍵,【New SubProject。。。】。之後新增的子工程就像平時建立帶有UI的工程一樣,我選擇的是繼承QWidget。我的名稱是PluginWidget
②修改PluginWidget
新建立的PluginWidget包含有main。cpp,將它刪除。
修改PluginWidget。peo,將 TEMPLATE = app 改為TEMPLATE = lib;新增CONFIG += plugin
【外掛編寫步驟】
③宣告一個外掛類,該類繼承自QObject和該外掛要提供的介面
之後新增一個繼承QObject的類,我的名稱是MyFirstPlugin。該類就是外掛類。
此時你的工程看起來是這個樣子:
這步還沒結束,還要再繼承AbstractInterface類,但是在myfirstplugin。h中無法直接包含abstractinterface。h,這時需要修改PluginWidget。pro。根據建立的目錄新增INCLUDEPATH += 。。/MainWidget,這時就可以include abstractinterface。h了。
順便說下,透過拆分不同的。pro也可以解耦程式,以後根據具體情況再和大家分享。
【外掛編寫步驟】
④使用Q_INTERFACES ()宏告訴Qt的元物件系統有關介面的資訊
Q_INTERFACES(AbstractInterface)
【外掛編寫步驟】
⑤使用Q_PLUGIN_METADATA ()宏匯出外掛
Q_PLUGIN_METADATA(IID “Welcome to pay attention to the public number。” FILE “myfirstplugin。json”)
注意下myfirstplugin。json,這是我們echoplugin中直接改名複製的,這個需要有。echoplugin是Qt自帶的外掛例程。
外掛編寫最後一步是實現createPluginWidget(QWidget *parent) 。
QWidget *MyFirstPlugin::createPluginWidget(QWidget *parent)
{
PluginWidget *pluginWidget = new PluginWidget(parent);
return pluginWidget;
}
PluginWidget是外掛邏輯實現的子工程,該工程中我僅在UI中添加了兩個label。
至此,外掛編寫完成。
此時執行工程會生成一個外掛,如圖:
宿主程式載入外掛
①在應用程式中使用QPluginLoader載入外掛
宿主程式中有一個AbstractInterface物件
遍歷PluginWidget目錄下的檔案,如果例項化成功則使用qobject_cast()測試外掛是否實現了給定的介面。【應用程式擴充套件外掛步驟的③和④】
foreach(QString fileName, pluginsDir。entryList(QDir::Files)) {
QPluginLoader pluginLoader(pluginsDir。absoluteFilePath(fileName));
QObject *plugin = pluginLoader。instance();
if(plugin)
{
m_pluginInterface = qobject_cast
if(m_pluginInterface)
{
m_pluginInterface->createPluginWidget(ui->pluginWidget);
ok = true;
}
}
}
在主UI中添加了一個Widget(ui->pluginWidget)和一個測試按鈕。最後效果如下:
總結:
外掛建立完以及載入後,整個流程就像官網描述的一樣。對沒有基礎的同志來講還是有一定難度,所以我就又自己搭建了一遍。
過程中涉及到了Qt的子工程、qmake的使用等。
Qt的外掛從C++的角度來講就是C++純虛擬函式的應用,需要規定介面,由外掛去實現,宿主程式只負責呼叫。
需要工程原始碼的私聊~