1. 程式人生 > 其它 >QT 自定義工程封裝成DLL,並在另一個QT程式中使用

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字串,說明動態庫已經正常使用了。