为了解决书院填综测的烦人问题,我决定使用比较熟悉的Qt框架编写一套自动填写综测的程序。其中涉及到读取xlsx文件,这就要用到外部的库。没想到装这个库踩了这么多坑,写个博客记录一下。学习CMake已经不得不提上日程了。
安装QXlsx库
Qt 6.7.3 (MSVC 2022 64-bit)
1
|
git clone https://github.com/QtExcel/QXlsx.git
|
由于我们使用MSVC,可以参考官网(使用 cmake | QXlsx)的构建方式,但不能完全照搬。
使用管理员权限启动Qt 6.7.3 (MSVC 2022 64-bit)的终端(位于...\Qt\6.7.3\msvc2022_64\bin\qtenv2.bat
,在【开始】界面搜索qt即可)
此时我们应当先将目录调整到./QXlsx
下,之后:
接下来进行配置构建和安装参数,这与官网的教程有些许不同:
1
|
cmake ../QXlsx/ -DCMAKE_INSTALL_PREFIX=E:/ProgramFile/CodingLibs/QXlsx/install_msvc2022_release
|
其中-DCMAKE_INSTALL_PREFIX=...
是设定库的安装根目录,一般都会放到项目名称/install
下。
官网的教程中给出有另一个参数-DCMAKE_BUILD_TYPE=Release
仅对单配置生成器(如 Makefile、Ninja)有效,对于 Visual Studio 这种多配置生成器,实际构建类型由--config
参数在构建阶段指定,所以在此处不需要填写。
接下来进行构建:
1
|
cmake --build . --config Release
|
这里与官网不同的就是多了参数--config Release
,这与上文阐述的原理相同。
接下来进行安装:
1
|
cmake --install . --config Release
|
接下来展示完整的命令行:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
Setting up environment for Qt usage...
Remember to call vcvarsall.bat to complete environment setup!
E:\ProgramFile\Qt\6.7.3\msvc2022_64>cd ../../../CodingLibs/QXlsx
E:\ProgramFile\CodingLibs\QXlsx>mkdir build
E:\ProgramFile\CodingLibs\QXlsx>cd build
E:\ProgramFile\CodingLibs\QXlsx\build>cmake ../QXlsx/ -DCMAKE_INSTALL_PREFIX=E:/ProgramFile/CodingLibs/QXlsx/install #这里不是install_msvc2022_release是因为仅作展示
-- Building for: Visual Studio 17 2022
-- Selecting Windows SDK version 10.0.22621.0 to target Windows 10.0.22631.
-- The CXX compiler identification is MSVC 19.42.34435.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.42.34433/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - not found
-- Found Threads: TRUE
-- Performing Test HAVE_STDATOMIC
-- Performing Test HAVE_STDATOMIC - Success
-- Found WrapAtomic: TRUE
-- Could NOT find WrapVulkanHeaders (missing: Vulkan_INCLUDE_DIR)
-- Configuring done (5.1s)
-- Generating done (0.2s)
-- Build files have been written to: E:/ProgramFile/CodingLibs/QXlsx/build
E:\ProgramFile\CodingLibs\QXlsx\build>cmake --build . --config Release
适用于 .NET Framework MSBuild 版本 17.12.12+1cce77968
1>Checking Build System
Automatic MOC for target QXlsx
Building Custom Rule E:/ProgramFile/CodingLibs/QXlsx/QXlsx/CMakeLists.txt
xlsxcellrange.cpp
xlsxcontenttypes.cpp
xlsxdrawinganchor.cpp
xlsxrichstring.cpp
xlsxworkbook.cpp
xlsxabstractooxmlfile.cpp
xlsxcellreference.cpp
xlsxdatavalidation.cpp
xlsxdrawing.cpp
xlsxsharedstrings.cpp
xlsxworksheet.cpp
xlsxabstractsheet.cpp
xlsxchart.cpp
xlsxdatetype.cpp
xlsxformat.cpp
xlsxsimpleooxmlfile.cpp
xlsxzipreader.cpp
xlsxcell.cpp
xlsxchartsheet.cpp
xlsxdocpropsapp.cpp
正在生成代码...
正在编译...
xlsxmediafile.cpp
xlsxstyles.cpp
xlsxzipwriter.cpp
xlsxcellformula.cpp
xlsxcolor.cpp
xlsxdocpropscore.cpp
xlsxnumformatparser.cpp
xlsxtheme.cpp
xlsxcelllocation.cpp
xlsxconditionalformatting.cpp
xlsxdocument.cpp
xlsxrelationships.cpp
xlsxutility.cpp
mocs_compilation_Release.cpp
正在生成代码...
QXlsx.vcxproj -> E:\ProgramFile\CodingLibs\QXlsx\build\Release\QXlsxQt6.lib
Building Custom Rule E:/ProgramFile/CodingLibs/QXlsx/QXlsx/CMakeLists.txt
E:\ProgramFile\CodingLibs\QXlsx\build>cmake --install . --config Release
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/lib/QXlsxQt6.lib
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/include/QXlsxQt6/xlsxabstractooxmlfile.h
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/include/QXlsxQt6/xlsxabstractsheet.h
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/include/QXlsxQt6/xlsxabstractsheet_p.h
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/include/QXlsxQt6/xlsxcellformula.h
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/include/QXlsxQt6/xlsxcell.h
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/include/QXlsxQt6/xlsxcelllocation.h
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/include/QXlsxQt6/xlsxcellrange.h
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/include/QXlsxQt6/xlsxcellreference.h
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/include/QXlsxQt6/xlsxchart.h
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/include/QXlsxQt6/xlsxchartsheet.h
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/include/QXlsxQt6/xlsxconditionalformatting.h
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/include/QXlsxQt6/xlsxdatavalidation.h
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/include/QXlsxQt6/xlsxdatetype.h
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/include/QXlsxQt6/xlsxdocument.h
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/include/QXlsxQt6/xlsxformat.h
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/include/QXlsxQt6/xlsxglobal.h
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/include/QXlsxQt6/xlsxrichstring.h
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/include/QXlsxQt6/xlsxworkbook.h
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/include/QXlsxQt6/xlsxworksheet.h
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/lib/cmake/QXlsxQt6/QXlsxQt6Targets.cmake
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/lib/cmake/QXlsxQt6/QXlsxQt6Targets-release.cmake
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/lib/cmake/QXlsxQt6/QXlsxQt6Config.cmake
-- Installing: E:/ProgramFile/CodingLibs/QXlsx/install/lib/cmake/QXlsxQt6/QXlsxQt6ConfigVersion.cmake
|
为了能够在调试的时候使用,还需要重复上述过程,安装一遍Debug版!
使用QXlsx库
在项目的CMakeLists.txt
添加如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
cmake_minimum_required(VERSION 3.16)
project(StdEvalGoPre VERSION 0.1 LANGUAGES CXX)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# >>> 查找Qt库
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
# >>> 设置QXlsx的安装路径(替换为实际安装路径)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(QXLSX_INSTALL_PATH "E:/ProgramFile/CodingLibs/QXlsx/install_msvc2022_debug")
else()
set(QXLSX_INSTALL_PATH "E:/ProgramFile/CodingLibs/QXlsx/install_msvc2022_release")
endif()
# >>> 将QXlsx的安装路径添加到CMake的搜索路径
list(APPEND CMAKE_PREFIX_PATH ${QXLSX_INSTALL_PATH})
# >>> 查找QXlsx库(根据使用的Qt版本选择)
if(${QT_VERSION_MAJOR} EQUAL 6)
find_package(QXlsxQt6 REQUIRED)
else()
find_package(QXlsxQt5 REQUIRED)
endif()
set(PROJECT_SOURCES
main.cpp
mainwindow.cpp
mainwindow.h
mainwindow.ui
util/excelreader.cpp
util/excelreader.h
)
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
qt_add_executable(StdEvalGoPre
MANUAL_FINALIZATION
${PROJECT_SOURCES}
)
else()
if(ANDROID)
add_library(StdEvalGoPre SHARED
${PROJECT_SOURCES}
)
else()
add_executable(StdEvalGoPre
${PROJECT_SOURCES}
)
endif()
endif()
# >>> 链接库(添加QXlsx的链接)
target_link_libraries(StdEvalGoPre PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
QXlsx::QXlsx # 添加QXlsx链接
)
if(${QT_VERSION} VERSION_LESS 6.1.0)
set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.StdEvalGoPre)
endif()
set_target_properties(StdEvalGoPre PROPERTIES
${BUNDLE_ID_OPTION}
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)
include(GNUInstallDirs)
install(TARGETS StdEvalGoPre
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
if(QT_VERSION_MAJOR EQUAL 6)
qt_finalize_executable(StdEvalGoPre)
endif()
|