设想
项目文件较多,全部放在一个目录下就像依托答辩。
希望能将头文件放入
include
,ui文件放入
ui
,源文件放入
src
。
为了将Qt代码和一般非Qt代码分离开,进一步地:
- 将Qt源文件放入
qt_src
,普通源文件放入src
- 将Qt头文件放入
qt_include
,普通头文件放入include
- 将Qt ui文件放入
ui
。
并且使用
set(CMAKE_AUTOUIC ON)
、
set(CMAKE_AUTOMOC ON)
来让它自己处理。
过程中还是遇到一些问题,通过看官方文档和其他人的提问得以解决,在这里分享一下。
目录结构 && CMakeLists.txt
简化问题,就暂时只搞了顶层一个
CMakeLists.txt
。
(这里只添加了必须的,如果你使用Qt Creator,最好将头文件、ui文件什么的都加进去,不然它里面看不到)
cmake_minimum_required(VERSION 3.1)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_PREFIX_PATH /opt/Qt/6.3.2/gcc_64 /opt/paddlepaddle)
set(EXE main)
project(${EXE})
aux_source_directory(qt_src SRC)
aux_source_directory(src SRC)
aux_source_directory(qt_src SRC)
FILE(GLOB QT_INC "qt_include/*.h")
list(APPEND CMAKE_AUTOUIC_SEARCH_PATHS "ui")
add_executable(${EXE}${SRC}${QT_INC})
find_package(Qt6 REQUIRED COMPONENTS Widgets)
find_package(OpenCV 4 REQUIRED)
find_package(FastDeploy REQUIRED)
target_include_directories(${EXE} PUBLIC
${FASTDEPLOY_INCS} include qt_include)
target_link_directories(${EXE} PUBLIC /usr/lib/seetaface6)
target_link_libraries(${EXE}
PUBLIC Qt6::Widgets
${OpenCV_LIBS}${FASTDEPLOY_LIBS}
SeetaAgePredictor600
SeetaAuthorize
SeetaEyeStateDetector200
SeetaFaceAntiSpoofingX600
SeetaFaceDetector600
SeetaFaceLandmarker600
SeetaFaceRecognizer610
SeetaFaceTracking600
SeetaGenderPredictor600
SeetaPoseEstimation600
SeetaQualityAssessor300
tennis_haswell
tennis_pentium
tennis_sandy_bridge
tennis)
主要看一下根目录,设想里面已经说了我的放置策略。
## 项目根目录
$ ls
build CMakeLists.txt include qt_include qt_src src ui
下面是目录详细内容,不过不是我们的重点。
## 普通源文件目录
$ ls src
app.cpp FaceAction_demo.cpp PPMatting_StaticLib_cpu.cpp video.cpp
emotion.cpp handler.cpp step.cpp
FaceAction.cpp model.cpp to.cpp
## 普通头文件目录
$ ls include
app.h FaceAction.h model.h step.h video.h
emotion.h handler.h PPMatting_StaticLib_cpu.h to.h
## Qt代码源文件目录
$ ls qt_src
cv2seetaimage.cpp main.cpp register_widget.cpp user_info.cpp
faceinfo.cpp mainfunction.cpp seetafacetools.cpp
facelogin.cpp mainwindow.cpp settingmodel.cpp
login_widget.cpp register_info.cpp trans.cpp
## Qt头文件目录
$ ls qt_include
cv2seetaimage.h login_widget.h register_info.h settingmodel.h
faceinfo.h mainfunction.h register_widget.h trans.h
facelogin.h mainwindow.h seetafacetools.h user_info.h
## ui文件目录
$ ls ui
facelogin.ui mainfunction.ui register_info.ui user_info.ui
login_widget.ui mainwindow.ui register_widget.ui
问题 && 解决
1. 批量添加ui文件和.h文件
笨方法是手动,把文件一个一个加进去,这样不够方便。
对于源文件,我们都知道可以用
aux_source_directory()
来添加,但是它只会添加源文件,不会添加目录下的
.h
文件和
.ui
文件。
解决方法:
FILE(GLOB UI "ui/*.ui")
FILE(GLOB INC "include/*.h")
提一句,有看到说FILE GLOB邪恶的,也许有什么缺点,暂且没有过度关注。
2. AUTOUIC找不到ui文件
由于采用
set(CMAKE_AUTOUIC ON)
的方式处理ui文件,编译时会报错找不到ui文件。
需要将ui文件夹加入
AUTOUIC
的搜索目录,这样
AUTOUIC
处理时才能找到ui文件。
解决方法:
list(APPEND CMAKE_AUTOUIC_SEARCH_PATHS "ui")
注意:是
CMAKE_AUTOUIC_SEARCH_PATHS
,而不是
AUTOUIC_SEARCH_PATHS
。这个把我坑惨了。
接下来可能会继续报错找不到生成的对应的
ui_XXX.h
头文件,可以尝试以下选项之一:
set(CMAKE_INCLUDE_CURRENT_DIR ON)# 其实只要这一条就够了,后面两条似乎也可以。
include_directories(${CMAKE_BINARY_PATH})
include_directories(${CMAKE_CURRENT_BINRAY_PATH})
因为自动生成的
ui_XXX.h
头文件是在构建目录下的,添加它即可。
3. AUTOMOC找不到定义(
undefined to 'vtable for XXX'
)
这个是最让我头疼的,cmake官网也没有说怎么解决。(这部分还专门翻译了一下,见我的另一篇博客:cmake-qt AUTOMOC)
看到网上的解释,意思是如果你不在
add_executable()
中添加使用了Qt元系统的头文件,那么
AUTOMOC
就不会处理这些头文件。
所以我们把Qt的头文件加入到
add_executable()
即可,这也是我为什么将普通头文件和Qt头文件分离开的原因之一(因为普通头文件不需要,虽然加上也没错)。
add_executable(${EXE}${SRC}${INC})
4. 资源文件
- 待办
我想后面如果要添加资源文件,那么可能会有类似的问题,遇到了再回来补充。
版权归原作者 barbyQAQ 所有, 如有侵权,请联系我们删除。