QT 自定义工程封装成DLL,并在另一个QT程序中使用

首先新建一个Library工程

QT 自定义工程封装成DLL,并在另一个QT程序中使用

 

QT 自定义工程封装成DLL,并在另一个QT程序中使用

 

命名为WidgetLib ,之后就默认下一步即可,如果需要添加额外的模块,可以在.pro文件中  语句QT +=  后面自己添加

工程新建之后文件列表如下所示

QT 自定义工程封装成DLL,并在另一个QT程序中使用

 

此时的文件中还没有ui文件,如果要封装带界面的动态库,需要右键点击工程->add new 

QT 自定义工程封装成DLL,并在另一个QT程序中使用

 

 

 在新弹出的窗口中选择Qt -> Qt设计师界面类

QT 自定义工程封装成DLL,并在另一个QT程序中使用

 

将其命名为与当前工程相同的名字,以覆盖之前不带ui界面的文件。

 

之后会弹出如下两个窗口,分别点击OK  和 Yes to All

QT 自定义工程封装成DLL,并在另一个QT程序中使用

 

 

 QT 自定义工程封装成DLL,并在另一个QT程序中使用

 

 

 此时可以看到新的工程文件下面多出了 .ui文件

QT 自定义工程封装成DLL,并在另一个QT程序中使用

 

 

 不过此时的工程还不能直接打包成动态库,因为旧的文件被覆盖掉了,新的文件无法打包成动态库,因此需要对新的文件进行修改

此时新的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文件

QT 自定义工程封装成DLL,并在另一个QT程序中使用

 

 

 

不过在此之前,我们还需要在界面上添加以下组件,以验证封装成DLL之后库的可用性。

我们在这个界面上添加一个按钮,并给这个按钮添加对应的槽函数

QT 自定义工程封装成DLL,并在另一个QT程序中使用

 

void WidgetLib::on_pushButton_clicked()
{
    qDebug()<<"aaaaaaaaaaaaaa";
}

然后点击构建按钮,生成动态库文件

生成的库文件在它自己的Debug文件夹下

 QT 自定义工程封装成DLL,并在另一个QT程序中使用

还需要用到一个文件就是它自己的头文件,widgetlib_global.h也一定要带上

 QT 自定义工程封装成DLL,并在另一个QT程序中使用

 此时,动态库封装就已经算完成了,需要用到的文件也就是上面红框标记出来的四个。

 

之后就是在另一个新的工程中使用这个动态库

创建一个新的带界面的工程

QT 自定义工程封装成DLL,并在另一个QT程序中使用

 

 

 之后现在工程LibTest文件夹下添加两个新的文件夹lib 和 include

 将widgetlib.h和widgetlib_global.h文件放到include文件夹中,将WidgetLib.lib放到lib文件夹中

然后在LibTest.pro文件中添加如下语句,引入动态库

INCLUDEPATH += $$PWD/include
LIBS += -L$$PWD/lib -lWidgetLib

QT 自定义工程封装成DLL,并在另一个QT程序中使用

 

 

 

然后我们开始编辑mainwindow.ui

QT 自定义工程封装成DLL,并在另一个QT程序中使用

 

 

 添加一个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查看动态库的可用性了。

不过这时我们会遇到一个问题,就是程序异常结束没法运行成功

QT 自定义工程封装成DLL,并在另一个QT程序中使用

 

 

 这是因为我们还有一个文件没有用上,那就是dll文件,我们还需要将WidgetLib.dll文件放到LibTest.exe同级 的文件夹下面,否则程序运行时找不到动态库,程序就会崩溃

由于此时是debug阶段,LibTest.exe文件在debug文件夹下,因此我们将dll放到这里

QT 自定义工程封装成DLL,并在另一个QT程序中使用

 

 同理,当release打包之后,dll依然放到exe文件的同级目录中即可

此时,再点击运行按钮

程序便启动成功了

QT 自定义工程封装成DLL,并在另一个QT程序中使用

 

 点击PushButton按钮,跳转到了第二个界面上

QT 自定义工程封装成DLL,并在另一个QT程序中使用

 

 再点击打印按钮

QT 自定义工程封装成DLL,并在另一个QT程序中使用

 

 可以看到下面打印了aaaaaaaaaa字符串,说明动态库已经正常使用了。

 

上一篇:PyQt5安装与PyCharm配置Qt Designer


下一篇:Python 开发:制作一个简易的点菜系统(附源码)