上一篇文章介绍了作者开发应用程序用到的编译器,编辑器和调试器,本篇文章用于介绍作者通常使用的工程目录和工程文件(对于Qt来说,是后缀名为.pro的文件),以及工程文件内容编写。
以当前应用为例,作者会在计算机操作系统任一文件夹下建立如下文件夹与工程文件,作为源文件保存位置(在windows命令窗口使用tree命令):
F:\SMFRAME-WORK-MASTER
├─bin
├─config
├─data
├─file
├─includes
├─lib
├─setup
└─src
├─base
├─gui
└─Logic
其中:
- bin:保存生成的可执行文件,以及额外的动态链接库
- config:保存程序配置文件,针对程序或者设备本身的元信息。
- data:保存参数文件,程序的输入输出文件。
- file:保存参考资料文件。
- includes:保存动态链接库对应的lib文件和程序生成的静态链接文件。
- setup:保存安装脚本和打包安装程序时需要额外包含的模块。
- src:保存源文件,作者一般使用三个源文件夹保存项目的不同抽象层次,其中:
- base:保存通用的底层抽象定义的源文件,例如通用的状态、变量和状态机定义,并编译成静态链接库使用。
- logic:保存处理逻辑源文件,特定项目使用的模块也在此文件夹中保存,并编译成静态链接库使用。
- gui:保存图形用户接口实现源文件,换言之,程序界面文件,以避免界面和逻辑实现的耦合,是程序的兼容性更强。
其中,src文件夹中包含的所有文件如下:
F:\SMFRAME-WORK-MASTER\SRC
│ Makefile
│ project.pro
│ project.pro.user
│ project.pro.user.01aed67
│ project.pro.user.8ed6e04
│
├─base
│ │ base.h
│ │ base.pro
│ │ base.pro.user
│ │ cprecisetime.cpp
│ │ cprecisetime.h
│ │ Makefile
│ │ Makefile.Debug
│ │ Makefile.Release
│ │ makefilepath.cpp
│ │ makefilepath.h
│ │ object.cpp
│ │ object.h
│ │ state.cpp
│ │ state.h
│ │ thing.cpp
│ │ thing.h
│ │ vardesc.cpp
│ │ vardesc.h
│ │ vardesctable.cpp
│ │ vardesctable.h
│ │ variant.cpp
│ │ variant.h
│ │ variants.cpp
│ │ variants.h
│ │ vsi_pause.cpp
│ │ vsi_pause.h
│ │ vs_idle.cpp
│ │ vs_idle.h
│ │ vs_work.cpp
│ │ vs_work.h
│ │ v_msg.cpp
│ │ v_msg.h
│ │ v_msgqueue.cpp
│ │ v_msgqueue.h
│ │ v_state.cpp
│ │ v_state.h
│ │ v_statemachine.cpp
│ │ v_statemachine.h
│ │
│ ├─debug
│ │ base_pch.obj
│ │ base_pch.pch
│ │ cprecisetime.obj
│ │ makefilepath.obj
│ │ object.obj
│ │ state.obj
│ │ thing.obj
│ │ vardesc.obj
│ │ vardesctable.obj
│ │ variant.obj
│ │ variants.obj
│ │ varmsg.obj
│ │ varmsgqueue.obj
│ │ varstate.obj
│ │ varstatemachine.obj
│ │ varstate_idle.obj
│ │ varstate_pause.obj
│ │ varstate_work.obj
│ │ vsi_pause.obj
│ │ vs_idle.obj
│ │ vs_work.obj
│ │ v_msg.obj
│ │ v_msgqueue.obj
│ │ v_state.obj
│ │ v_statemachine.obj
│ │
│ └─release
├─gui
│ │ cmopenglwidget.cpp
│ │ cmopenglwidget.h
│ │ gui.h
│ │ gui.pro
│ │ gui.pro.user
│ │ main.cpp
│ │ mainwindow.cpp
│ │ mainwindow.h
│ │ mainwindow.ui
│ │ Makefile
│ │ Makefile.Debug
│ │ Makefile.Release
│ │ qtw_varlist.cpp
│ │ qtw_varlist.h
│ │ qw_ball.cpp
│ │ qw_ball.h
│ │ ui_mainwindow.h
│ │
│ ├─debug
│ │ cmopenglwidget.obj
│ │ gui_pch.obj
│ │ gui_pch.pch
│ │ main.obj
│ │ mainwindow.obj
│ │ moc_cmopenglwidget.cpp
│ │ moc_cmopenglwidget.obj
│ │ moc_mainwindow.cpp
│ │ moc_mainwindow.obj
│ │ moc_mvariantslist.cpp
│ │ moc_mvariantslist.obj
│ │ moc_qballwidget.cpp
│ │ moc_qballwidget.obj
│ │ moc_qtw_varlist.cpp
│ │ moc_qtw_varlist.obj
│ │ moc_qw_ball.cpp
│ │ moc_qw_ball.obj
│ │ mvariantslist.obj
│ │ qballwidget.obj
│ │ qtw_varlist.obj
│ │ qw_ball.obj
│ │
│ └─release
└─Logic
│ logic.h
│ logic.pro
│ Logic.pro.user
│ Makefile
│ Makefile.Debug
│ Makefile.Release
│ vsmt_allsystem.cpp
│ vsmt_allsystem.h
│ vsmt_ball.cpp
│ vsmt_ball.h
│ vsm_thread.cpp
│ vsm_thread.h
│ vsw_allsystem.cpp
│ vsw_allsystem.h
│ vsw_ball.cpp
│ vsw_ball.h
│
├─debug
│ Logic_pch.obj
│ Logic_pch.pch
│ varsm_thread.obj
│ varsm_thread_allsystem.obj
│ varsm_thread_ball.obj
│ varstate_work_allsystem.obj
│ varstate_work_ball.obj
│ vsmt_allsystem.obj
│ vsmt_ball.obj
│ vsm_thread.obj
│ vsw_allsystem.obj
│ vsw_ball.obj
│
└─release
makefile文件、obj文件、pch文件pro文件以及*.pro.user均可以通过项目创建或者编译是直接生成,通过IDE菜单命令也可以向pro文件中添加描述代码,以及类的声明和源文件。但部分描述代码需要在Qt中打开手动编译,因此,四个pro项目文件的内容如下所示:
Project.pro
TEMPLATE = subdirs
SUBDIRS += $$PWD/base \
$$PWD/logic \
$$PWD/gui
logic.depends=base
gui.depends=logic
该项目文件位于src文件夹下,其内容完全由作者编辑,用于作为子项目目录索引其他项目并配置编译依赖关系,换言之,只需要双击打开该文件就可以浏览所有的三个子项目。该pro文件可以通过IDE中创建空白pro项目菜单命令生成,如下图所示:

Base.pro
#-------------------------------------------------
#
# Project created by QtCreator 2022-05-05T08:15:13
#
#-------------------------------------------------
QT += xml
QT -= gui
TARGET = base
TEMPLATE = lib
CONFIG += staticlib
SOURCES += \
object.cpp \
state.cpp \
thing.cpp \
vardesc.cpp \
vardesctable.cpp \
variant.cpp \
variants.cpp \
makefilepath.cpp \
v_msg.cpp \
v_msgqueue.cpp \
v_state.cpp \
vs_idle.cpp \
vsi_pause.cpp \
vs_work.cpp \
v_statemachine.cpp \
cprecisetime.cpp
HEADERS += \
object.h \
state.h \
thing.h \
base.h \
makefilepath.h \
vs_idle.h \
vsi_pause.h \
vs_work.h \
v_statemachine.h \
v_msg.h \
vardesc.h \
variant.h \
vardesctable.h \
variants.h \
v_msgqueue.h \
v_state.h \
cprecisetime.h
unix {
target.path = /usr/lib
INSTALLS += target
}
#-------------------------------------------------
# 额外添加
#-------------------------------------------------
DESTDIR = ../../lib
INCLUDEPATH += ../../includes
PRECOMPILED_HEADER = base.h
在重构过N遍之后的新的项目框架中,作者不再使用windows的ini文件作为项目配置文件(通用性不好,读写速度奇慢,作者做过的大型项目中只能优化到1秒多),而是用xml作为项目的配置文件(兼容性好,读写速度快,相同的项目只需要几十毫秒,且xml文件可以无限添加层级,便于定义变量特性,取值范围,单位之类,非常完美),因此在配置文件中添加QT += xml一行,将DOM(用于解析xml文件)模块包含到项目中(可以直接包含头文件使用),其他文件由IDE创建静态链接库时自动生成,作者在最后添加了三行描述代码,其中:
- DESTDIR:表示输出文件路径,即生成的base.lib文件输出至lib文件夹中。
- INCLUDEPATH:表示额外包含的头文件所在文件夹。
- PRECOMPILED_HEADER:预编译头文件,如果大多数cpp源文件都包含了同一头文件,在编译器预处理之前,先编译该头文件可以极大提升编译速度,类似于windows程序中的stdafx.h文件,只不过QT可以设置预编译文件名称,相对于windows来说就极大的柔性。
该pro文件可以通过IDE中创建C++库项目菜单命令生成,如下图所示:

Logic.pro
#-------------------------------------------------
#
# Project created by QtCreator 2022-05-05T14:46:50
#
#-------------------------------------------------
QT += xml
QT -= gui
TARGET = Logic
TEMPLATE = lib
CONFIG += staticlib
SOURCES += \
vsm_thread.cpp \
vsmt_allsystem.cpp \
vsmt_ball.cpp \
vsw_allsystem.cpp \
vsw_ball.cpp
HEADERS += logic.h \
vsm_thread.h \
vsmt_allsystem.h \
vsmt_ball.h \
vsw_allsystem.h \
vsw_ball.h
unix {
target.path = /usr/lib
INSTALLS += target
}
#-------------------------------------------------
# 额外添加
#-------------------------------------------------
DESTDIR = ../../lib
INCLUDEPATH += ../base
INCLUDEPATH += ../../includes
PRECOMPILED_HEADER = logic.h
该项目文件与base.pro类似,但是额外增加了一行INCLUDEPATH += ../base,这表明该项目中的cpp源文件可以直接引用base项目中的头文件,这样文件操作就不用像作者在编译windows项目将所有头文件都复制到include文件夹中。
Gui.pro
#-------------------------------------------------
#
# Project created by QtCreator 2022-05-06T16:38:32
#
#-------------------------------------------------
QT += core gui
QT += xml
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = gui
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp \
qtw_varlist.cpp \
qw_ball.cpp \
cmopenglwidget.cpp
HEADERS += mainwindow.h \
gui.h \
qtw_varlist.h \
qw_ball.h \
cmopenglwidget.h
FORMS += mainwindow.ui
win32: LIBS += -L../../lib/ -lbase#$$PWD/
INCLUDEPATH += ../../#$$PWD/
DEPENDPATH += ../../#$$PWD/
win32:!win32-g++: PRE_TARGETDEPS += ../../lib/base.lib#$$PWD/
else:win32-g++: PRE_TARGETDEPS += ../../lib/libbase.a#$$PWD/
win32: LIBS += -L$$PWD/../../lib/ -llogic
INCLUDEPATH += $$PWD/../../
DEPENDPATH += $$PWD/../../
win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../lib/logic.lib
else:win32-g++: PRE_TARGETDEPS += $$PWD/../../lib/liblogic.a
#-------------------------------------------------
# 额外添加
#-------------------------------------------------
DESTDIR = ../../bin
INCLUDEPATH += ../base
INCLUDEPATH += ../logic
INCLUDEPATH += ../../includes
INCLUDEPATH += ../../includes/vld_include
PRECOMPILED_HEADER = gui.h
win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../lib/vld_lib/ -lvld
INCLUDEPATH += $$PWD/../../lib/vld_lib
DEPENDPATH += $$PWD/../../lib/vld_lib
用户界面项目文件大部分的描述代码也由IDE自动生成,这里只需要注意作者手动添加的额外的头文件搜索目录,以及手动添加的vld动态链接库(vld.lib从安装位置拷贝到项目lib/vld_lib文件夹,vld.dll拷贝值bin文件夹下,vld.h拷贝到includes/vld_include文件夹下)用于检测程序退出时的内存泄漏情况。
退出时内存泄漏并不重要,但是其代表这程序可能会出现持续的内存分配而不释放就很重要,这代表着程序运行足够的时间之后就会耗尽内存,导致程序崩溃。
该pro文件可以通过IDE中创建视窗项目菜单命令生成,如下图所示:

下一章:讲解作者对变量的通用定义。
D7FECB19D148C1AD1D829F1CD0E23DB0
发表回复
要发表评论,您必须先登录。