全網最詳細的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

Qt外掛建立及載入

建立完成後工程是空的,選中工程後滑鼠右鍵,【New SubProject。。。】,如圖。之後新增的子工程就像平時建立帶有UI的工程一樣,我選擇的是繼承QWidget。

Qt外掛建立及載入

此時編譯執行的話會顯示一個為空的QWidget窗體。建立成功後大概向下面的樣子

Qt外掛建立及載入

透過外掛使應用程式可以被擴充套件

【應用程式擴充套件外掛步驟】

①編寫僅具有純虛擬函式的類

選中資料夾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)

此時透過外掛使應用程式可以被擴充套件的前兩步就完成了,後面兩步之後在宿主程式中載入外掛時再介紹。此時你的工程看起來是這個樣子:

Qt外掛建立及載入

再新增一個子工程用於編寫外掛

①再次新增一個子工程

選中工程【MyFirstPlugin】後滑鼠右鍵,【New SubProject。。。】。之後新增的子工程就像平時建立帶有UI的工程一樣,我選擇的是繼承QWidget。我的名稱是PluginWidget

②修改PluginWidget

新建立的PluginWidget包含有main。cpp,將它刪除。

修改PluginWidget。peo,將 TEMPLATE = app 改為TEMPLATE = lib;新增CONFIG += plugin

【外掛編寫步驟】

③宣告一個外掛類,該類繼承自QObject和該外掛要提供的介面

之後新增一個繼承QObject的類,我的名稱是MyFirstPlugin。該類就是外掛類。

此時你的工程看起來是這個樣子:

Qt外掛建立及載入

這步還沒結束,還要再繼承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。

至此,外掛編寫完成。

Qt外掛建立及載入

此時執行工程會生成一個外掛,如圖:

Qt外掛建立及載入

宿主程式載入外掛

①在應用程式中使用QPluginLoader載入外掛

宿主程式中有一個AbstractInterface物件

Qt外掛建立及載入

遍歷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(plugin);

if(m_pluginInterface)

{

m_pluginInterface->createPluginWidget(ui->pluginWidget);

ok = true;

}

}

}

在主UI中添加了一個Widget(ui->pluginWidget)和一個測試按鈕。最後效果如下:

Qt外掛建立及載入

總結:

外掛建立完以及載入後,整個流程就像官網描述的一樣。對沒有基礎的同志來講還是有一定難度,所以我就又自己搭建了一遍。

過程中涉及到了Qt的子工程、qmake的使用等。

Qt的外掛從C++的角度來講就是C++純虛擬函式的應用,需要規定介面,由外掛去實現,宿主程式只負責呼叫。

需要工程原始碼的私聊~