创建一个静态链接库项目,设计各种需要导出的类,包括具有UI的窗体类、对话框类,编译后可以生成一个lib文件(MSVC编译器生成后缀为“.lib”的文件,MinGW编译器生成后缀为“.a” 的文件),在另一个应用程序里使用这个lib文件和类的头文件(不需要cpp源文件),就可以静态编译到应用程序里。这种方式适合于在小组开发时,每个人负责自己的部分,使用其他人设计的代码时只能使用而不能看到或修改源代码,便于项目代码的管理。
创建静态链接库
创建静态链接库项目,单击Qt Creator的“File” 一 “New File or Project”菜单项,在出现的 “New File or Project”对话框中选择Projects组里的Library,在右侧的具体类别中再选择C++ Library,单击“Choose...”按钮后出现向导对话框。
在“Location”页面,设置“Name”给项目命名,例如myStaticLib,再选择项目保存目录。
在“Details”对话框的Type下拉列表框里选择“Statically Linked Library”,Qt Module选择需要包含的 Qt模块,再下一步是输入类的名称。本实例将设计的一个QPen属性设置对话框QDialogPen作为静态库的导出类,所以在图中的类定义界面上输入的类名称为QDialogPen,头文件和源程序文件名会自动生成。单击“Next”按钮,直至结束即可。
这样生成的静态库项目myStaticLib包括3个文件:myStaticLib.pro、qdialogpen.h和 qdialogpen.cpp。
导出类QDialogPen的设计实现
如果已经设计好了导出类QDialogPen,可以将QDialogPen 类相关的 3 个文件 qdialogpen.h、qdialogpen.cpp 和 qdialogpen.ui复制到myStaticLib项目的源文件目录下,覆盖自动生成的两个文件,并且将qdialogpen.ui添加到项目中。
如果没有之前没有设计导出类,也可以现在设计。首先创建UI界面,单击Qt Creator的“File” 一 “New File or Project”菜单项,在出现的 “New File or Project”对话框中选择Qt组里的Qt Designer Form,名称设置为qdialogpen.ui。其次,完成QDialogPen类的定义和功能实现。QDialogPen类相关的3个文件内容不是本文重点,在此不做介绍。
项目配置文件及编译
项目配置文件myStaticLib.pro是对本项目的设置,其内容如下:
QT += widgets
TARGET = myStaticLib
TEMPLATE = lib
CONFIG += staticlib
SOURCES += qdialogpen.cpp
HEADERS += qdialogpen.h
unix {
target.path = $[QT_INSTALL_PLUGINS]/generic
}
!isEmpty(target.path): INSTALLS += target
FORMS += qdialogpen.ui
TEMPLATE=lib定义项目模板是库,而不是应用程序。
CONFIG += staticlib配置项目为静态库。
TARGET = myStaticLib定义项目编译后生成的目标文件名称是myStaticLib。
注意静态库项目可以使用MinGW或MSVC编译器编译,但是项目编译生成的文件与使用的编译器有关。若使用MSVC编译,编译后会生成一个库文件myStaticLib.lib;若使用MinGW编译,编译后会生成一个库文件 libmyStaticLib.a。
release和debug模式下编译生成的都是相同的文件名,并不会为debug版本自动添加一个字母“d”,但是在release和debug模式下编译应用程序时,需要使用相应版本的库文件。
静态链接库的使用
创建一个基于QMainWindow的应用程序LibUser,在项目源程序目录下新建一个include目录,根据使用的编译器复制不同的文件。
- 若使用MSVC编译器,将release版本的 myStaticLib.lib复制到这个include目录下,将debug版本的myStaticLib.lib更名为 myStaticLibd.lib复制到这个include目录下。
- 若使用 MinGW 编译器,就将 libmyStaticLib.a和libmyStaticLibd.a(debug版本)复制到 include目录里。
- 将静态库项目myStaticLib下的qdialogpen.h复制到这个include目录下。
在项目管理目录树里右键单击LibUser项目,在快捷菜单里单击“Add Library...”菜单项,在出现的向导对话框里首先选择添加的库类型为“External Library”,在向导第二步设置需要导入的静态库文件(见下图)。
设置添加的静态库信息
首先选择需要导入的库文件myStaticLib.lib,连接类型里必须选择Static,因为这是静态库, 勾选Add “d” suffix for debug version,使得在debug模式下编译应用程序时将自动调用debug版本的库文件myStaticLibd.lib。
设置完成后,QtCreator将自动更改项目配置文件LibUser.pro,增加以下的内容,主要是设置 了包含文件和依赖项的路径,增加了LIBS设置。
win32:CONFIG(release, debug|release): LIBS += -L$PWD/include/ -lmyStaticLib
else:win32:CONFIG(debug, debug|release): LIBS += -L$PWD/include/ -lmyStaticLibd
INCLUDEPATH += $PWD/include
DEPENDPATH += $PWD/include
win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $PWD/include/libmyStaticLib.a
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $PWD/include/libmyStaticLibd.a
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $PWD/include/myStaticLib.lib
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $PWD/include/myStaticLibd.lib
编译应用程序LibUser,使用MSVC或MinGW编译器,在release或debug模式下都可以编译,运行程序效果如图所示。单击“设置Pen”桉钮可以设置划线的Pen属性,并在主窗体上绘制一个矩形框。
应用程序LibUser运行效果
主窗体程序比较简单,MainWindow类的定义如下:
class MainWindow : public QMainWindow
{
Q_OBJECT
private:
QPen mPen;
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
protected:
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
private slots:
void on_actionPen_triggered();
private:
Ui::MainWindow *ui;
};
paintEvent()事件在窗体上绘制一个矩形,使用了QPen类型的私有变量mPen作为绘图的画笔。action_Pen的响应代码调用静态库里的QDialogPen的静态函数getPen设置画笔属性。
void MainWindow::paintEvent(QPaintEvent *event)
{ // 绘图
Q_UNUSED(event);
QPainter painter(this);
QRect rect(0,0,width(),height()); // viewport 矩形区
painter.setViewport(rect);// 设置 Viewport
painter.setWindow(0, 0, 100,50);// 设置窗口大小,逻辑坐标
painter.setPen(mPen);
painter.drawRect(10,10,80,30);
}
void MainWindow::on_actionPen_triggered()
{ // 设置Pen
bool ok=false;
QPen pen=QDialogPen::getPen(mPen,ok);
if(ok){
mPen=pen;
this->repaint();
}
}
本实例将一个可视化设计的对话框QDialogPen封装到一个静态库里,也可以将任何C++类、函数封装到静态库,其实现方法是一样的。