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_MODULESCore Gui WidgetsMultimediaQml 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里有更豐富的命令,比如檢測目錄是否存在等