Qt版本:

创建动态库
文件,新建文件或项目。选择c++库

起名为QTLib


勾选QtGui

设置类名,点下一步,完成

项目创建完成后,新建一个界面文件。
文件,新建文件或项目。选择Qt 设计师界面

选择mainwindow

ui文件名字

点击完成

之后编辑创建的ui文件,简单的添加一个按钮

项目目录结构

打开qtlib.h
查看QTLib类的定义,有一个QTLIBSHARED_EXPORT宏
并在qtlib.h中包含了一个头文件
查看QTLib_global.h
#ifndef QTLIB_GLOBAL_H
#define QTLIB_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(QTLIB_LIBRARY)
# define QTLIBSHARED_EXPORT Q_DECL_EXPORT
#else
# define QTLIBSHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // QTLIB_GLOBAL_H
若定义QTLIB_LIBRARY,则QTLIBSHARED_EXPORT被替换为Q_DECL_EXPORT,而没有则被替换为Q_DECL_IMPORT
在项目文件QTLib.pro中,有这样一句
DEFINES += QTLIB_LIBRARY
因此Qt库项目中,QTLIBSHARED_EXPORT被替换为Q_DECL_EXPORT,对类进行导出
而使用Qt库的项目中,QTLIBSHARED_EXPORT会被替换为Q_DECL_IMPORT
下面生成ui_xxx.h
在项目文件中加入
QT+= widgets
并执行qmake
之后点击编译,会弹出以下对话框,因为生成的是库文件,无法直接运行,因此关闭即可

在编译文件夹下产生了ui头文件ui_mainwindow.h

在qtlib.h包含ui头文件
#include "ui_mainwindow.h"
在界面编辑器中,找到ui对象的名称

在qtlib.h中创建一个命名域UI,并且在其中加入ui类的前向声明
在QTLib类中创建一个ui类指针
并在构造函数的成员初始化列表中创建ui类,在构造函数中调用setupUi方法
再次编译。在编译目录下的debug文件夹下面会成功生成库文件,其中QTLib.dll是我们需要的动态库

测试:
新建一个项目,简单的一个Qt控制台应用,使用它来测试我们生成的动态库

项目名字


项目创建完成后,将QTLib源代码文件夹下的qtlib.h、QTLib_global.h以及编译目录下生成的ui_mainwindow.h都拷贝到TestLib源代码文件夹下

在TestLib项目文件中加入
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
在main.cpp包含qtlib.h,创建QTLib类并使用
main.cpp
#include <QApplication>
#include "qtlib.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTLib ql;
ql.show();
return a.exec();
}
由于编译与运行时需要使用到动态库,在项目文件中加入
LIBS += -LC:\Qt\projects\QTLib-build-Desktop_Qt_5_0_1_MinGW_32bit-Debug\debug -lQTLib
-L后面跟链接的库目录,即QTLib生成的QTLib.dll所在的目录
-l后面跟的链接的库名称,链接动态库QTLib.dll
对于每次修改项目文件后,都需要执行一次qmake
之后编译运行得到QTLib的界面。

注意:
由于我使用的是基于MinGW的qt版本,对于g++,动态库只会生成dll文件,不会生成对应的lib文件,使用时只需要在项目文件中使用命令链接对应的dll文件即可。
而对于基于MSVC的qt,生成动态库同时会生成lib文件,在使用时只需要对项目右键,添加库,外部库,选择相应的lib文件与路径就可以了

源代码:
QTLib:
QTLib.pro
#-------------------------------------------------
#
# Project created by QtCreator 2022-05-27T14:05:55
#
#-------------------------------------------------
QT+= widgets
TARGET = QTLib
TEMPLATE = lib
DEFINES += QTLIB_LIBRARY
SOURCES += qtlib.cpp
HEADERS += qtlib.h\
QTLib_global.h
unix:!symbian {
maemo5 {
target.path = /opt/usr/lib
} else {
target.path = /usr/lib
}
INSTALLS += target
}
FORMS += \
mainwindow.ui
qtlib.h
#ifndef QTLIB_H
#define QTLIB_H
#include "QTLib_global.h"
#include "ui_mainwindow.h"
namespace Ui {
class MainWindow;
}
class QTLIBSHARED_EXPORT QTLib:public QMainWindow
{
public:
QTLib();
private:
Ui::MainWindow *ui;
};
#endif // QTLIB_H
QTLib_global.h
#ifndef QTLIB_GLOBAL_H
#define QTLIB_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(QTLIB_LIBRARY)
# define QTLIBSHARED_EXPORT Q_DECL_EXPORT
#else
# define QTLIBSHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // QTLIB_GLOBAL_H
qtlib.cpp
mainwindow.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>379</width>
<height>328</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>130</x>
<y>110</y>
<width>75</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>379</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
TestLib:
TestLib.pro:
#-------------------------------------------------
#
# Project created by QtCreator 2022-05-27T14:18:57
#
#-------------------------------------------------
QT += core
QT -= gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = TestLib
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
LIBS += -LC:\Qt\projects\QTLib-build-Desktop_Qt_5_0_1_MinGW_32bit-Debug\debug -lQTLib
main.cpp