CLion开发Qt桌面
IDE:CLion Qt
Qt版本:5.12
学习正点原子的嵌入式Linux开发板时,使用Qt Creator写代码不是很方便,遂尝试使用CLion搭建Qt开发环境。
一、CLion的Qt环境搭建
1,配置工具链
找到Qt的安装目录,此处为E:\Tools\Develop\Embedded\Qt。这里使用mingw64来编译工程,新建一个MinGW,把工具集的路径设置为Qt对应的mingw64路径
找到Qt工程的目录,确保路径上没有中文。此处为正点原子imx6ull资料盘里的Qt综合例程源码
在里面创建一个CMakeLists文件
2,使用CLion打开工程
右键工程 ,使用CLion打开
弹出的界面选择刚才创建的工具链
由于创建的CMakeLists中没有写任何东西,所以构建时会出问题
二、编写CMakeLists
1,添加资源文件
资源文件和头文件我们可以从.pro里获取,或者自己手动打或者使用通配符
使用Alt + J 扩选“\”,把“\”删除。Ctrl +Alt + L格式化文件,使其规整。(后面会给出CMakeLists)
Qt除了.cpp外还需要.h和.qrc,因为Qt会把.h和.qrc转为.cpp。由于CMake缓存目录里也会有.h之类的,故不能直接使用*.h
也正是由于Qt编译的特殊性,它并不需要如一般程序指定头文件目录
2,添加Qt库
编写CMakeLists要注意,使用CLion创建Qt程序的CMakeLists有可能会导致库路径寻找失败。比如下图,使用find_package寻找后,头也不回的去找python用的虚拟环境Anaconda3的目录。而且是屡教不改
最后编译的结果就是,头文件找到了,但链接的库确实python虚拟环境下的Qt库,会报一堆缺少__imp__*定义的错误
解决办法就是在前面指定搜索目录,定义Qt5_DIR变量这种方法没有什么效果。如果你的搜索路径仍不变,那么删除CMake缓存,重新CMake
查找模块和链接模块总是需要输入相同的名称,这里可以先定义一个变量存储,然后在变量里的名称添加前缀,即可得到链接库的名称
3,运行程序
直接运行程序,你会发现报下面错误,0xC0000135是很常见的错误,即缺少dll
我们回到Qt,会发现Qt在运行这一步也直接执行程序,但它不会报错。这是因为Qt在执行程序时会添加一个环境变量——Qt库的目录,这样程序在运行时就能自动搜索dll,不会报错了。
我们可以在构建目标里添加这个环境变量,点击紫色的$
点击+,然后添加PATH和对应的bin目录
右边的bin目录是你所选的Qt库里的bin
E:\Tools\Develop\Embedded\Qt\5.15.2\mingw81_64\bin
确定后再次执行,就可以正常运行了
4,完整CMakeLists
C++标准可以不指定,后面删除了复制dll的步骤,改为添加环境变量
cmake_minimum_required(VERSION 3.30) project(QtDesktop) set(CMAKE_CXX_STANDARD 11) #打开全局moc set(CMAKE_AUTOMOC ON) #打开全局uic set(CMAKE_AUTOUIC ON) #打开全局rcc,如果没有使用qrc,此句可以去掉 set(CMAKE_AUTORCC ON) #设置工程包含当前目录,使用*.ui文件时,需要加上这句,否则找不到头文件 set(CMAKE_INCLUDE_CURRENT_DIR ON) # ---------添加头文件目录---------- #include_directories( # cameramedia # fileview # weather # music # media # wireless # tcpclient # desktop # udpchat # photoview # iotest # sensor # iotest # radio #) # ---------添加资源文件---------- file(GLOB_RECURSE SRC "main.cpp" "qml.qrc" "cameramedia/*.cpp" "cameramedia/*.h" "desktop/*.cpp" "desktop/*.h" "fileview/*.cpp" "fileview/*.h" "iotest/*.cpp" "iotest/*.h" "media/*.cpp" "media/*.h" "music/*.cpp" "music/*.h" "photoview/*.cpp" "photoview/*.h" "radio/*.cpp" "radio/*.h" "sensor/*.cpp" "sensor/*.h" "tcpclient/*.cpp" "tcpclient/*.h" "tcpserver/*.cpp" "tcpserver/*.h" "udpchat/*.cpp" "udpchat/*.h" "weather/*.cpp" "weather/*.h" "wireless/*.cpp" "wireless/*.h" ) # 定义 Qt 模块名称 set(QT_MODULES Core Gui Widgets Multimedia Qml Network ) # ------------查找Qt库------------ set(CMAKE_PREFIX_PATH "E:/Tools/Develop/Embedded/Qt/5.15.2/mingw81_64") find_package(Qt5 REQUIRED COMPONENTS ${QT_MODULES} ) # ------------添加可执行文件------------ add_executable(${PROJECT_NAME} ${SRC}) # ------------链接Qt库------------ set(QT_LIBRARIES) foreach(MODULE ${QT_MODULES}) list(APPEND QT_LIBRARIES "Qt5::${MODULE}") endforeach() target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES})
三、添加外部工具
1,Designer
打开设置,找到外部工具,再点击+添加工具,desinger程序是在你所用的Qt库的bin目录(前面的环境变量也是这个)
传入的实参就是需要运行的文件名,工作目录选择工程目录
$FileName$
$ProjectFileDir$
2,UIC
与前面相同,再添加一个外部工具Qt UIC,它的目的是把.ui文件转为.h文件。所以这里的实参,是把.ui文件输出为.h。
所谓实参就是给外部工具传入的参数,下面这一句等价为在命令行里输入
uic $FileName$ -o ui_$FileNameWithoutExtension$.h
里面的变量名会被替换为具体的文件名
$FileName$ -o ui_$FileNameWithoutExtension$.h
$FileDir$
实际上前面在CMakeLists里开启了自动UIC,它会自动把添加进来的ui文件转为.h。此外,正点原子这个工程使用的是Qt Quick 技术栈,并非Qt Widgets,事实上是用不到UIC的
3,使用
使用时,可以右键对应文件,选择对应的外部工具
4,QMLSCENE(预览QML)
这个工具挺有用的,是预览qml文件用的,此工具是位于Qt库里的qmlscence.exe
E:\Tools\Develop\Embedded\Qt\5.15.2\mingw81_64\bin\qmlscene.exe
$FileName$
$FileDir$
需要说明一点,正点原子的相关例程里,由于qml会导入一些别的资源,那么这个预览工具就不能正常预览了,它适合单个无依赖文件或者依赖都在同一个目录
5,设计无法开启
刚使用Qt Creator时,左边栏中【设计】是灰的,这需要开启一个插件,然后重启
点击上面的【帮助】,然后点击【关于插件】,把QmlDesigner勾选上,确定后再重启
接下来就可以自由切换编辑和设计模式了
在【编辑】->【偏好选项】里找到Qt Quick,可以选择默认打开Qt Design Studio
界面元素设计这块,还是Qt Creator比较好用,可以无缝衔接Qt Design Studio
四、使用Qt Creator原生工具
除了使用CMake构建外,也可以通过外部工具的方法来使用Qt Creator配置好的构建工具和命令。不过实际使用过程中,反应巨慢,提示信息又很反人类,还不如直接使用Qt Creator。不建议使用,但可以作为兴趣了解一下。
1,Qt Creator的构建运行过程
Qt Creator的构建和运行都在项目配置里写好的,在下图的项目配置界面,可以看到构建这个步骤实际上是分为两步执行的,qmake和make步骤
把qmake步骤展开,可以看到下面调用
E:/Tools/Develop/Embedded/Qt/5.15.2/mingw81_64/bin/qmake.exe E:\Program\Embedded\Qt\imx6ull\QDesktop\QDesktop.pro -spec win32-g++ "CONFIG+=debug" "CONFIG+=qml_debug" && E:/Tools/Develop/Embedded/Qt/Tools/mingw810_64/bin/mingw32-make.exe qmake_all
这个调用过程看起来只有qmake这个过程,实际上还有make过程,从命令里可以看到“&&”符号,这个在终端调用里会把前面两个程序运行都执行。不过如果放在CLion的外部工具或者构建命令里,是不能使用"&&"的,因为对于它来说,一个外部工具或者构建命令只能运行一个程序,实参里一般是不允许再运行别的程序,除非这个外部工具是终端
所以qmake步骤实际是有下面两个过程
- 先qmake生成Makefile
qmake.exe E:\Program\Embedded\Qt\imx6ull\QDesktop\QDesktop.pro -spec win32-g++ "CONFIG+=debug" "CONFIG+=qml_debug"
- 再使用make构建qmake_all目标
mingw32-make.exe qmake_all
至于下面这个make步骤要做的事情很简单,编译all目标,“in”及“in”后面的内容并不是参数,只是告诉你在哪个目录。
make -j16
清理步骤与前面的make all一样,清晰明了
运行步骤前面说过,添加了一个环境变量用于检索dll
2,CLion自定义构建目标
从前面的分析可知,构建过程可以拆分为三个步骤,qmake生成Makefile、make执行qmake_all目标、make执行all目标,清理步骤只有一个目标,即make执行clean目标
先在构建目标里找到自定义构建应用程序
前面分析过构建有三个目标,我们要确保最后一个是make all,不然没法编译源文件。也就是说构建要做的事情是make all,那么其他两个步骤需要放在构建前,我们在下面的【执行前】添加一个运行外部工具
先添加一个qmake,用于生成Makefile,程序是所选Qt库bin目录里的程序,实参就是前面Qt Creator里qmake执行的命令。工作目录会在选择程序后默认为程序所在目录,由于已经指定了.pro文件,那么这个工作目录可以不用改
E:\Program\Embedded\Qt\imx6ull\QDesktop\QDesktop.pro -spec win32-g++ "CONFIG+=debug" "CONFIG+=qml_debug"
再添加一个外部工具,用于执行make qmake_all。这个make命令是需要在前面生成的Makefile的目录执行,我们可以在make后加一个参数"-C"来指定工作目录,或者直接把工具目录改为MakeFile所在目录
-C E:\Program\Embedded\Qt\imx6ull\QDesktop\build\Desktop_Qt_5_15_2_MinGW_64_bit-Debug qmake_all
添加好外部工具之后,记得顺序不能乱,我们要使用的这两个外部工具,qmake是在前面的
点击确定后,把这个运行外部工具给放到构建前面
接下来是添加构建目标,点击这个【配置自定义构建目标】,这里已经提前配置过了,所以会有一个目标
配置的这个目标,使用的工具链是前面配置过的,构建目标和清理目标就是make -j16和make clean -j16
点击旁边的三点,添加外部工具,与前面一致,这里就不赘述了
添加可执行文件这一步,就添加build目录的QDesktop程序,环境变量与前面一样,添加Qt库bin目录。
需要注意的是,我们这里只是简单配置,所以不会自动生成build相关目录,如果没有在Qt Creator里预先构建一遍的话,这里运行这个自定义目标会提示缺少目录什么的。
最后我们构建这个目标,从提示信息里就可以窥视到,这完全就是按照Qt Creator的路子走一遍(当然下面检测到了项目没有做任何改变)
我们在main里随便定义一个变量
哪怕这个变量人畜无害,也会罗里吧嗦给出一堆警告(不是报错),当然这可能是生成的Makefile里开了-Wall
运行与前面相同,只不过它会在运行前坚定地指定构建三步骤
除了按部就班地使用自定义构建目标外,也可以通过CMakeLists里添加自定义命令达到一样的效果,并且CMakeLists里有更丰富的命令,比如检测目录是否存在等