QT 自定義工程封裝成DLL,並在另一個QT程式中使用
首先新建一個Library工程
命名為WidgetLib ,之後就預設下一步即可,如果需要新增額外的模組,可以在.pro檔案中 語句QT += 後面自己新增
工程新建之後檔案列表如下所示
此時的檔案中還沒有ui檔案,如果要封裝帶介面的動態庫,需要右鍵點選工程->add new
在新彈出的視窗中選擇Qt -> Qt設計師介面類
將其命名為與當前工程相同的名字,以覆蓋之前不帶ui介面的檔案。
之後會彈出如下兩個視窗,分別點選OK 和 Yes to All
此時可以看到新的工程檔案下面多出了 .ui檔案
不過此時的工程還不能直接打包成動態庫,因為舊的檔案被覆蓋掉了,新的檔案無法打包成動態庫,因此需要對新的檔案進行修改
此時新的widgetlib.h檔案內容如下
#ifndef WIDGETLIB_H #define WIDGETLIB_H #include <QWidget> namespace Ui { class WidgetLib; } class WidgetLib : public QWidget { Q_OBJECT public: explicit WidgetLib(QWidget *parent = nullptr); ~WidgetLib(); private: Ui::WidgetLib *ui; }; #endif // WIDGETLIB_H
需要將其修改為下面的內容
#ifndef WIDGETLIB_H #define WIDGETLIB_H #include <QWidget> #include "widgetlib_global.h" namespace Ui { class WidgetLib; } class WIDGETLIBSHARED_EXPORT WidgetLib : public QWidget { Q_OBJECT public: explicit WidgetLib(QWidget *parent = nullptr); ~WidgetLib(); private: Ui::WidgetLib *ui; }; #endif // WIDGETLIB_H
即 : 需要新增標頭檔案#include "widgetlib_global.h" 以及 在類名前新增WIDGETLIBSHARED_EXPORT 語句。
WIDGETLIBSHARED_EXPORT語句可以在標頭檔案widgetlib_global.h中直接複製過來,就是下方程式碼中,紅色標記的部分
widgetlib_global.h #ifndef WIDGETLIB_GLOBAL_H #define WIDGETLIB_GLOBAL_H #include <QtCore/qglobal.h> #if defined(WIDGETLIB_LIBRARY) # define WIDGETLIBSHARED_EXPORT Q_DECL_EXPORT #else # define WIDGETLIBSHARED_EXPORT Q_DECL_IMPORT #endif #endif // WIDGETLIB_GLOBAL_H
之後,點選下方構建按鈕即可生成對應的dll檔案
不過在此之前,我們還需要在介面上新增以下元件,以驗證封裝成DLL之後庫的可用性。
我們在這個介面上新增一個按鈕,並給這個按鈕新增對應的槽函式
void WidgetLib::on_pushButton_clicked() { qDebug()<<"aaaaaaaaaaaaaa"; }
然後點選構建按鈕,生成動態庫檔案
生成的庫檔案在它自己的Debug資料夾下
還需要用到一個檔案就是它自己的標頭檔案,widgetlib_global.h也一定要帶上
此時,動態庫封裝就已經算完成了,需要用到的檔案也就是上面紅框標記出來的四個。
之後就是在另一個新的工程中使用這個動態庫
建立一個新的帶介面的工程
之後現在工程LibTest資料夾下新增兩個新的資料夾lib 和 include
將widgetlib.h和widgetlib_global.h檔案放到include資料夾中,將WidgetLib.lib放到lib資料夾中
然後在LibTest.pro檔案中新增如下語句,引入動態庫
INCLUDEPATH += $$PWD/include
LIBS += -L$$PWD/lib -lWidgetLib
然後我們開始編輯mainwindow.ui
新增一個StackedWidget元件,第一頁上面放一個按鈕,點選這個按鈕,跳轉到第二頁,第二頁放置我們封裝的動態庫介面
先給pushbutton新增槽函式
void MainWindow::on_pushButton_clicked() { ui->stackedWidget->setCurrentIndex(1); }
然後,我們在Mainwidow中新增一個WidgetLib物件
#include <QMainWindow> //包含動態庫的標頭檔案 #include <widgetlib.h> #include <widgetlib_global.h> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void on_pushButton_clicked(); private: Ui::MainWindow *ui; WidgetLib *lib;//建立WidgetLib物件 };
在建構函式中
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow) { ui->setupUi(this); lib = new WidgetLib;//給WidgetLib物件分配記憶體 lib->setParent(ui->stackedWidget->widget(1));//指定lib父物件,即讓這個物件顯示在哪一個介面,這裡指定StackedWidget的第二頁 }
此時,就可以執行LibTest.exe檢視動態庫的可用性了。
不過這時我們會遇到一個問題,就是程式異常結束沒法執行成功
這是因為我們還有一個檔案沒有用上,那就是dll檔案,我們還需要將WidgetLib.dll檔案放到LibTest.exe同級 的資料夾下面,否則程式執行時找不到動態庫,程式就會崩潰
由於此時是debug階段,LibTest.exe檔案在debug資料夾下,因此我們將dll放到這裡
同理,當release打包之後,dll依然放到exe檔案的同級目錄中即可
此時,再點選執行按鈕
程式便啟動成功了
點選PushButton按鈕,跳轉到了第二個介面上
再點選列印按鈕
可以看到下面列印了aaaaaaaaaa字串,說明動態庫已經正常使用了。