首先新建一個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字符串,說明動態庫已經正常使用了。
補充:一下為本文的補充部分,后面我在網上看到了可以將已有的可以以GUI進程運行的工程封裝為DLL的方法,有了此方法就不需要再向上面一樣繞一大圈,上面的方法與下面的方法相比,實在過於繁瑣,而且調試也及其不方便
假如我現在有一個名為CustomMessageBox的GUI進程,想要將其改為DLL,需要做如下修改,注意紅色部分為類名的大寫,需要根據實際情況修改紅色文本部分的內容。
1.修改配置文件
1 #TEMPLATE = app
2
3 DEFINES += CUSTOMMESSAGEBOX_LIBRARY
4 TEMPLATE = lib
2.在導出類的頭文件上加如下代碼
1 #if defined(CUSTOMMESSAGEBOX_LIBRARY) 2 # define CUSTOMMESSAGEBOXSHARED_EXPORT Q_DECL_EXPORT 3 #else 4 # define CUSTOMMESSAGEBOXSHARED_EXPORT Q_DECL_IMPORT 5 #endif
3.修改導出類定義
1 //class CustomMessageBox : public QDialog
2 class CUSTOMMESSAGEBOXSHARED_EXPORT CustomMessageBox : public QDialog
4.編譯
若是 MinGW32
編譯器,在編譯之后會在文件夾下找到 ***.dll
和 ***.a
文件;若是 MSVC
編譯器,則應該是 ***.dll
和 ***.lib
。
5.使用
在使用該庫的程序中,新建一個 include
文件夾,將 ***.a
文件 和 導出類的頭文件
復制進這個文件夾,在程序中引入該頭文件即可。在編譯之后,將不同模式編譯下的 dll
文件放入程序編譯后的文件夾中,才能正常運行程序。
參考網址:https://www.cnblogs.com/ybqjymy/p/14024700.html