----------------------------------------------------------------
創(chuàng)新互聯(lián)是一家專注于網(wǎng)站設(shè)計制作、網(wǎng)站制作與策劃設(shè)計,市北網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)10年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:市北等地區(qū)。市北做網(wǎng)站價格咨詢:028-86922220
網(wǎng)頁版課程源碼 提取碼:1uy7
引言
----------------------------------------------------------------
上一節(jié)我們介紹了pri文件的作用與使用方法,在項目開發(fā)尤其是大型項目開發(fā)中,pri文件的使用是非常重要的。當(dāng)我們開展不同的項目開發(fā)時,這些項目有非常多的配置項都是完全一樣的。因此,建立一套完整的pri體系變得非常重要。
?
正文
----------------------------------------------------------------
???一般情況下,我們會建立一套常用的pri文件,他們各自負(fù)責(zé)不同的功能,比如有的負(fù)責(zé)處理編譯選項;有的負(fù)責(zé)處理目錄設(shè)置。為了方便,我們把這些不同的pri整合成一個文件來介紹,當(dāng)然,大家也可以根據(jù)需要把這個文件拆成不同的pri文件。
???注:本節(jié)的內(nèi)容默認(rèn)您的項目使用gcc編譯器。
???直接給出gui_base.pri文件:
?
代碼清單02-06-01
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. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126.? | ########################################################################### #注意:此文件用于放置本次課程各子項目的公共設(shè)置, #在各子項目的 QT 工程文件中通過 include 語句包含該pri文件。 #需要提前定義如下系統(tǒng)環(huán)境變量: # TRAINDEVHOME? ?根目錄: ?其下是bin、lib、src等子目錄。 # TRAINBUILDTYPE編譯版本: debug|release|all # TRAINBUILDBIT ?編譯位數(shù): 32|64 ########################################################################### ? #需先通過環(huán)境變量 TRAINDEVHOME 指定開發(fā)目錄 #由于 isEmpty 函數(shù)不能直接對環(huán)境變量進(jìn)行判斷,所以先將其放入一個臨時變量中 DEVHOME = $$(TRAINDEVHOME) isEmpty(DEVHOME) { ??? error('TRAINDEVHOME'環(huán)境變量必須被定義.) } #設(shè)置變量:系統(tǒng)執(zhí)行文件路徑、庫文件路徑、臨時文件生成路徑、頭文件包含路徑 TRAIN_BIN_PATH = $$(TRAINDEVHOME)/bin TRAIN_LIB_PATH = $$(TRAINDEVHOME)/lib TRAIN_OBJ_PATH = $$(TRAINDEVHOME)/obj TRAIN_SRC_PATH = $$(TRAINDEVHOME)/src TRAIN_UIC_PATH = $$(TRAINDEVHOME)/obj/uic TRAIN_INCLUDE_PATH = $$(TRAINDEVHOME)/include ? #設(shè)置所引用的庫文件的路徑 QMAKE_LIBDIR *= $$TRAIN_LIB_PATH ? DEPENDPATH *=? .\ ??????? $$TRAIN_INCLUDE_PATH ??????? INCLUDEPATH *=? .\ ??????? $$TRAIN_INCLUDE_PATH ? ########################################################################## # #不同平臺的編譯器設(shè)置 # ########################################################################## #獲取編譯 Qt 的編譯器類型 TRAIN_QMAKESPEC = $$(QMAKESPEC) ? #UNIX + gcc下聲明使用預(yù)編譯頭文件 #GCC 3.4及以后版本支持預(yù)編譯頭文件 unix{ ??? contains( ? TRAIN_QMAKESPEC, g++ ) { ??????? CONFIG ? *= precompile_header ??? } } #WIN32下聲明使用預(yù)編譯頭文件 win32{ ??? CONFIG ? *= precompile_header ??? ??? #去掉 strcpy 等編譯警告 ??? QMAKE_CXXFLAGS ? *= -wd4996 } ? #UNIX下編譯設(shè)置 unix{ ??? DEFINES ? *= unix __unix? } ? #WIN32下編譯設(shè)置 win32{ ??? DEFINES *= WIN32 } ? #激活 STL、RTTI、EXCEPTIONS 支持 CONFIG *= stl exceptions rtti #激活多線程、編譯警告 CONFIG *= thread warn_on ? #不同編譯版本相關(guān)的配置 BUILDTYPE = $$(TRAINBUILDTYPE) equals(BUILDTYPE,debug){ ??? CONFIG ? += debug ??? CONFIG ? -= release } equals(BUILDTYPE,release){ ??? CONFIG ? += release ??? CONFIG ? -= debug } equals(BUILDTYPE,all){ ??? CONFIG ? -= debug ??? CONFIG ? -= release ??? CONFIG ? += debug_and_release build_all } ? #指定代碼中宏定義 debug_and_release { ??? CONFIG(debug, ? debug|release) { ??? ??? DEFINES += TRAIN_DEBUG ??? } ??? CONFIG(release, ? debug|release) { ??? ??? DEFINES += TRAIN_RELEASE ??? } } else { ??? debug: ? DEFINES += TRAIN_DEBUG ??? release: ? DEFINES += TRAIN_RELEASE } ? #配置系統(tǒng)使用的編譯位數(shù)類型 BUILDBIT = $$(TRAINBUILDBIT) ? #不同編譯版本相關(guān)的配置 equals(BUILDBIT,32){ ??? #擴(kuò)展 32 位配置項 ??? CONFIG ? *= x86 ??? DEFINES ? *= TRAIN_32 } equals(BUILDBIT,64){ ??? #擴(kuò)展 64 位配置項 ??? CONFIG ? *= x64 ??? DEFINES ? *= TRAIN_64 } ? #指定不同編譯版本中間文件目錄 debug_and_release { ??? CONFIG(debug, ? debug|release) { ??? ??? TRAIN_OBJ_PATH = $$TRAIN_OBJ_PATH/debug ??? } ??? CONFIG(release, ? debug|release) { ??? ??? TRAIN_OBJ_PATH = $$TRAIN_OBJ_PATH/release ??? } } else { ??? debug:TRAIN_OBJ_PATH ? = $$TRAIN_OBJ_PATH/debug ??? release:TRAIN_OBJ_PATH ? = $$TRAIN_OBJ_PATH/release } |
???下面我們來詳細(xì)介紹一下這個pri文件。
?
1,開頭的聲明
???首先,在pri文件開頭有一個聲明,指明了需要創(chuàng)建的環(huán)境變量。也就是說,這個pri文件依賴于環(huán)境變量值,當(dāng)然,您也可以選擇不用環(huán)境變量,而是通過修改pri文件中的相關(guān)內(nèi)容來改變這些設(shè)置,但是使用環(huán)境變量會方便一些,因為不用每次都修改這個pri文件。
???這個pri文件用到的環(huán)境變量有3個,分別是:
??? 1)? TRAINDEVHOME
用來描述項目的根目錄,目錄結(jié)構(gòu)如下:
$TRAINDEVHOME
------bin?????????編譯好的運行程序所在目錄
------lib?????????編譯好的lib文件所在目錄
------include?????公共頭文件目錄,其下可以再分子目錄
------src?????????源代碼根目錄
------temp????? ???臨時文件目錄
?
2)? TRAINBUILDTYPE?
編譯版本,取值:
debug??????編譯debug版本
release????編譯release版本
all????????同時編譯debug、release版本,即兩個版本都編譯。
?
3)? TRAINBUILDBIT??
編譯位數(shù),取值:
32?????????編譯成32位程序
64?????????編譯成64位程序
?
???當(dāng)然了,QTDIR、QMAKESPEC是安裝完Qt后必不可少的環(huán)境變量,本文不再贅述。
?
2,環(huán)境變量檢查
1.?? ? ? 2.?? ? ? 3.?? ? ? 4.?? ? ? | DEVHOME = $$(TRAINDEVHOME) isEmpty(DEVHOME) { ??? error('TRAINDEVHOME'環(huán)境變量必須被定義.) } |
通過Qt的isEmpty()函數(shù)判斷環(huán)境變量是否存在,如果為空,則輸出錯誤信息并退出。
???因為isEmpty()只能使用自定義變量而無法使用環(huán)境變量,因此我們先定義了DEVHOME這個變量并賦值為環(huán)境變量值,然后用它進(jìn)行判斷。
?
3,公共目錄
1.?? ? ? 2.?? ? ? 3.?? ? ? 4.?? ? ? 5.?? ? ? 6.?? ? ? 7.?? ? ? 8.?? ? ? 9.?? ? ? 10.? ? 11.? ? 12.? ? 13.? ? 14.? ? 15.? ? 16.? ? | #設(shè)置變量:系統(tǒng)執(zhí)行文件路徑、庫文件路徑、臨時文件生成路徑、頭文件包含路徑 TRAIN_BIN_PATH = $$(TRAINDEVHOME)/bin TRAIN_LIB_PATH = $$(TRAINDEVHOME)/lib TRAIN_OBJ_PATH = $$(TRAINDEVHOME)/obj TRAIN_SRC_PATH = $$(TRAINDEVHOME)/src TRAIN_UIC_PATH = $$(TRAINDEVHOME)/obj/uic TRAIN_INCLUDE_PATH = ? $$(TRAINDEVHOME)/include ? #設(shè)置所引用的庫文件的路徑 QMAKE_LIBDIR *= $$TRAIN_LIB_PATH ? DEPENDPATH *=? .\ ??????? $$TRAIN_INCLUDE_PATH ??????? INCLUDEPATH *=? .\ ??????? $$TRAIN_INCLUDE_PATH |
???這里定義了可執(zhí)行程序目錄等路徑,都依賴于TRAINDEVHOME環(huán)境變量,如果您不想用環(huán)境變量,可以使用自定義變量來替換(需要注意自定義變量的語法跟環(huán)境變量不同)。
???上述變量都是公共路徑設(shè)置。在pro中引用本pri文件后,還可以繼續(xù)對這些變量值進(jìn)行引用加工(比如繼續(xù)追加目錄層級),從這些變量的名稱就可以對其用途略知一二,現(xiàn)在我們分別看一下。
表02-06-01
關(guān)鍵字 | 含義 |
TRAIN_BIN_PATH | 編譯完成的可執(zhí)行程序的存放路徑 |
TRAIN_LIB_PATH | 編譯完成的lib文件的存放路徑 |
TRAIN_OBJ_PATH | 編譯產(chǎn)生的臨時文件的根目錄 |
TRAIN_SRC_PATH | 源代碼的根目錄 |
TRAIN_UIC_PATH | 編譯ui文件產(chǎn)生的臨時文件根目錄(它是TRAIN_OBJ_PATH目錄的子目錄) |
TRAIN_INCLUDE_PATH | 項目的公共include目錄 |
QMAKE_LIBDIR | Qt關(guān)鍵字 設(shè)置所引用的庫文件的路徑。比如,編譯某個exe時如果用到了dll文件,那么這個變量用來告訴編譯器到哪個目錄去找所需的lib文件。 |
DEPENDPATH | Qt關(guān)鍵字 用來指明所依賴的頭文件路徑 |
INCLUDEPATH | Qt關(guān)鍵字 用來告訴編譯器頭文件的搜索目錄。 這樣的話,在源代碼中引用頭文件時,就可以直接寫文件名或者相對路徑,比如: ??? #include "header.h" ??? #include "base/basedll/header.h" 此處的目錄是相對于INCLUDEPATH,也就是: ??? $INCLUDEPATH/base/basedll/header.h |
??????? ???
4,編譯器設(shè)置
1.?? ? ? 2.?? ? ? 3.?? ? ? 4.?? ? ? 5.?? ? ? 6.?? ? ? 7.?? ? ? 8.?? ? ? 9.?? ? ? 10.? ? 11.? ? 12.? ? 13.? ? 14.? ? 15.? ? 16.? ? | #獲取編譯 Qt 的編譯器類型 TRAIN_QMAKESPEC ? = $$(QMAKESPEC) ? #UNIX ? + gcc下聲明使用預(yù)編譯頭文件 #GCC ? 3.4及以后版本支持預(yù)編譯頭文件 unix{ ??? contains( TRAIN_QMAKESPEC, g++ ) { ??????? CONFIG *= precompile_header ??? } } #WIN32下聲明使用預(yù)編譯頭文件 win32{ ??? CONFIG *= precompile_header ??? ??? #去掉strcpy等編譯警告 ??? QMAKE_CXXFLAGS *= -wd4996 } |
本部分內(nèi)容用來處理預(yù)編譯頭文件的內(nèi)容。gcc3.4及以后的版本支持預(yù)編譯頭文件,因此為了判斷gcc編譯器,我們使用了Qt的contains()函數(shù)。該函數(shù)也無法識別環(huán)境變量,因此我們定義了變量TRAIN_QMAKESPEC。 當(dāng)unix(linux也走pri中的unix分支)的編譯器為gcc時,CONFIG配置項就增加了預(yù)編譯頭文件的支持:
CONFIG *= precompile_header
windows下(pri中的win32分支,win32是Qt的關(guān)鍵字)默認(rèn)提供預(yù)編譯頭文件支持,因此無條件增加precompile_header的選項。
為了消除strcpy造成的4996編譯警告,我們增加如下語句:
??? QMAKE_CXXFLAGS *= -wd4996
?
5,宏定義
1.?? ? ? 2.?? ? ? 3.?? ? ? 4.?? ? ? 5.?? ? ? 6.?? ? ? 7.?? ? ? 8.?? ? ? 9.?? ? ? | #UNIX下編譯設(shè)置 unix{ ??? DEFINES ? *= unix __unix? } ? #WIN32下編譯設(shè)置 win32{ ??? DEFINES *= WIN32 } |
在代碼中,我們經(jīng)常需要判斷當(dāng)前運行程序的操作系統(tǒng)類型,因此需要預(yù)先定義操作系統(tǒng)類型宏,上述代碼就給出了在unix以及windows下的定義操作系統(tǒng)類型宏的方法,使用了DEFINES語法,這樣在源代碼中,我們就可以直接使用這些宏進(jìn)行判斷了。本部分內(nèi)容在上節(jié)進(jìn)行過講解,這里不再展開。
?
6,激活stl、rtti、exceptions支持
1.?? ? ? 2.?? ? ? | #激活 STL、RTTI、EXCEPTIONS 支持 CONFIG *= stl exceptions rtti |
???如果您使用stl庫,那么請激活stl支持。
???如果您使用異常處理,那么請激活exceptions。
???如果您需要運行時類型識別,那么請激活rtti。
???這些選項都是CONFIG配置項,可以單獨配置。
?
7,激活多線程,編譯
1.?? ? ? 2.?? ? ? | #激活多線程、編譯警告 CONFIG *= thread warn_on |
如果您的項目中用到多線程,請激活thread。因為本pri文件是公共pri,所以如果您的某個子模塊用不到多線程支持,您可以在子模塊的pro中禁用多線程,方法是在子模塊的pro中使用如下語句:
CONFIG -= thread
?
8,編譯成debug版還是release版本
1.?? ? ? 2.?? ? ? 3.?? ? ? 4.?? ? ? 5.?? ? ? 6.?? ? ? 7.?? ? ? 8.?? ? ? 9.?? ? ? 10.? ? 11.? ? 12.? ? 13.? ? 14.? ? 15. | # 不同編譯版本相關(guān)的配置 BUILDTYPE = $$(TRAINBUILDTYPE) equals(BUILDTYPE,debug){ ??? CONFIG ? += debug ??? CONFIG ? -= release } equals(BUILDTYPE,release){ ??? CONFIG ? += release ??? CONFIG ? -= debug } equals(BUILDTYPE,all){ ??? CONFIG ? -= debug ??? CONFIG ? -= release ??? CONFIG ? += debug_and_release build_all } |
???如果需要對我們的程序進(jìn)行調(diào)試,我們會選擇debug版本,因為debug版的程序含有很多調(diào)試信息,而如果我們需要發(fā)布版則使用release版本,因為它的執(zhí)行效率更高運行更快。此處我們使用了Qt的equals()函數(shù)來判斷編譯版本。同樣這個函數(shù)也不識別環(huán)境變量,因此我們定義了BUILDTYPE變量來進(jìn)行判斷。請注意,equals()函數(shù)中的第二個參數(shù)中的debug、release只是個字符串,下列語句中的debug、release才是Qt的關(guān)鍵字。
CONFIG+=debug
??? CONFIG -= release
???
9,程序運行時如何區(qū)分debug版還是releaes版
???有時候,我們在程序運行過程中,需要知道自己是debug版還是release版,該怎么做呢?
1.?? ? ? 2.?? ? ? 3.?? ? ? 4.?? ? ? 5.? ? ?? 6.?? ? ? 7.?? ? ? 8.?? ? ? 9.?? ? ? 10.? ? 11.? ? 12.? ? | # 指定代碼中宏定義 debug_and_release ? { ??? CONFIG(debug, debug|release) { ??? ??? ? DEFINES += TRAIN_DEBUG ??? } ??? CONFIG(release, debug|release) { ??? ??? ? DEFINES += TRAIN_RELEASE ??? } } ? else { ??? debug: DEFINES += TRAIN_DEBUG ??? release: DEFINES += TRAIN_RELEASE } |
???上述語法是分支判斷語法,其{}前面的字符串是CONFIG的配置項,比如此處的debug_and_release。我們使用上述方法得知當(dāng)前編譯版本并定義了相關(guān)的宏TRAIN_DEBUG、TRAIN_RELEASE。這樣在源代碼中就可以直接用這兩個宏來區(qū)分debug版與release版本了。請大家務(wù)必注意下列代碼的語法:
??? CONFIG(debug, debug|release)
???上述語句用來判斷是否正在編譯debug版本。
??? CONFIG(release, debug|release)
???上述語句用來判斷是否正在編譯release版本。
?
???而下面的語句用來區(qū)分debug編譯分支和release編譯分支,方法是在debug或者release后使用冒號(:)。
debug:DEFINES += TRAIN_DEBUG
release:DEFINES += TRAIN_RELEASE
???
10,程序運行時如何區(qū)分32位程序還是64位程序
???程序運行的時候,有可能需要知道自己被編譯成了32位還是64位,方法如下:
1.?? ? ? 2.?? ? ? 3.?? ? ? 4.?? ? ? 5.?? ? ? 6.?? ? ? 7.?? ? ? 8.?? ? ? 9.?? ? ? 10.? ? 11.? ? 12.? ? 13.? ? 14.? ? | # 配置系統(tǒng)使用的編譯位數(shù)類型 BUILDBIT = $$(TRAINBUILDBIT) ? # 不同編譯版本相關(guān)的配置 equals(BUILDBIT,32){ ??? # ? 32 位配置項 ??? CONFIG ? *= x86 ??? DEFINES ? *= TRAIN_32 } equals(BUILDBIT,64){ ??? # ? 64 位配置項 ??? CONFIG ? *= x64 ??? DEFINES ? *= TRAIN_64 } |
???方法與區(qū)分debug版本還是release版本類似,因此不再詳述。
?
11,區(qū)分debug版本、release版本的臨時文件
???編譯程序時,編譯同一個項目的debug版本與release版本會產(chǎn)生不同的臨時文件,我們當(dāng)然不希望這些臨時文件會相互覆蓋,因此我們需要為它們指定不同的目錄。
1.?? ? ? 2.?? ? ? 3.?? ? ? 4.?? ? ? 5.?? ? ? 6.?? ? ? 7.?? ? ? 8.?? ? ? 9.?? ? ? 10.? ? 11.? ? 12.? ? | # 指定不同編譯版本中間文件目錄 debug_and_release { ??? CONFIG(debug, ? debug|release) { ??? ??? TRAIN_OBJ_PATH = $$TRAIN_OBJ_PATH/debug ??? } ??? CONFIG(release, ? debug|release) { ??? ??? TRAIN_OBJ_PATH = $$TRAIN_OBJ_PATH/release ??? } } else { ??? debug:TRAIN_OBJ_PATH ? = $$TRAIN_OBJ_PATH/debug ??? release:TRAIN_OBJ_PATH ? = $$TRAIN_OBJ_PATH/release } |
???從上述代碼可以看出,debug版本與release版本產(chǎn)生的臨時文件分別存放到obj下面的debug目錄、release目錄,這樣就不會相互覆蓋了。
?
結(jié)語
----------------------------------------------------------------
???本節(jié)詳細(xì)介紹了如何為項目引入pri體系并且使它正常運轉(zhuǎn)起來。本文提到的pri使用了比較多的配置項,大家可以根據(jù)個人的需求調(diào)整其中的配置項。但是其中最常被修改的可能也就下面3個:
TRAINDEVHOME??根目錄,其下是bin、lib、src等子目錄。
TRAINBUILDTYPE編譯版本: debug|release|all
TRAINBUILDBIT?編譯位數(shù): 32|64
???原因就是使用者可能根據(jù)自己的項目需求創(chuàng)建了不同的環(huán)境變量名(比如不是TRAINDEVHOME,而是SOURCEHOME),或者干脆不用環(huán)境變量僅僅使用自定義變量。如果僅僅使用自定義變量,那么就需要將本pri中所有使用環(huán)境變量的地方改成使用自定義變量,而且一定要注意自定義變量的使用語法跟環(huán)境變量不同:
???環(huán)境變量: $$(環(huán)境變量名)
變量:???? $$變量名
???如果使用自定義變量,那么請注意項目的pro文件中,如果要引用該pri文件,那么也要進(jìn)行相應(yīng)修改:
代碼清單02-06-01
myprogram.pro
1.?? ? ? 2.?? ? ? | PRI_FILE_PATH = ../../ include ($$PRI_FILE_PATH/src/gui_base.pri) |
?
???本節(jié)內(nèi)容比較多,請大家慢慢消化。如果還是不知道該怎樣使用pri文件,請學(xué)習(xí)下節(jié)內(nèi)容開始練手吧。
----------------------------------------------------------------
《Qt入門與提高-GUI產(chǎn)品開發(fā)》目錄請?zhí)砑渔溄用枋?br />上一節(jié):KS02-05 pri 文件有啥用?
下一節(jié):KS03-01 怎樣實現(xiàn)國際化