如何判斷Windows, OS X, iOS, Android?...
啟稿: 2015/01/10
完稿: 2015/01/10
QT CueTai線索台
跨平台實作07-跨平台實作進階:採用外部資源檔,四作業系統自動判斷
雖然我們已經學會因應四種不同的作業系統平台如何加入個別的資源檔,但是每次當我們要編譯不同的作業系統就要進行不同pro設定與source code的更動,實在不方便;若QT可以自動判斷所要建置的作業系統平台而自行設定與更動改有多好,所以在此我們來研究QT是否有這樣的能力呢?
l Pro檔中的qmake語言
其實QT都知道我們準備進行何種作業系統平台的建置,因為我們都要如下圖所示先選擇所需要的Kit,就表示準備進行何種作業系統平台的建置,因此QT一定有相對應的Global變數或語言來記錄此種狀態。
首先我們來看前面四次範例實作針對不同的作業系統平台要採用外部資源檔,都要修改採用不同的巨集命令來進行,既然QT都知道我們準備進行何種作業系統平台的建置,那麼在pro檔中就有相對應的的qmake命令或語言;我們可以在QT說明畫面的搜尋欄位輸入keyword "qmake",得到一堆相關的說明,但我們現在不是要找qmake Variables巨集命令,而是要看QT如何在qmake建置中進行判斷及流程控制的語言,所以要查看的應該是下一頁所提到的qmake Language,如下所示:
將此說明往後移動可以看到"Scopes"章節及次章節"Scopes and Conditions",可以看到在QT pro檔內控制流程條件(condition)的文法如下:
<condition> {
<command or definition>
...
}
這種流程條件(condition)就如同C語言之while用法是一樣。
更有意思的是後面還有兩種作業系統的範例:
win32 {
SOURCES += paintwidget_win.cpp
}
macx {
CONFIG(debug, debug|release) {
HEADERS += debugging.h
}
}
這個範例就正好是我們要的QMake Language。
所以現在我們可以將前面四個作業系統的範例加入QMake Language彙整成以下的內容:
ResourcesFiles.files = \
../analogclock/Configure.txt \
../analogclock/audio/alarm.wav \
../analogclock/audio/bird.wav \
../analogclock/audio/cricketnight.wav \
../analogclock/audio/dolphin.wav \
../analogclock/audio/hour.wav \
../analogclock/audio/laser.wav \
../analogclock/audio/water.wav
macx:!win:!android:!ios {
ResourcesFiles.path = Contents/Resources
QMAKE_BUNDLE_DATA += ResourcesFiles
}
else : ios {
ResourcesFiles.path = resource
}
else : android {
ResourcesFiles.path = /assets
INSTALLS += ResourcesFiles
}
else {
ResourcesFiles.path = Resources
INSTALLS += ResourcesFiles
}
經過上述的修改,QT就會根據選擇的Kit,來建置不同的資源目錄以配合不同種作業系統平台所需的資源檔!
l 修改程式
同樣的,我們也需要有同樣的功能變數能在QT C++語言中可以應用,如此我們就可以配合不同種作業系統平台自行取用相對應的原始碼;這種功能就像是在C與C++中Compile用的Global巨集命令一樣,例如#ifdef等等;所以我們可以在QT說明畫面的搜尋欄位輸入keyword "global marco",得到"Global QT Declarations"如下:
在文章下方的搜尋區在鍵入MAC作進一步搜尋,可以得到非常有用的資料如下:
原來QT有提供Global巨集變數來判斷各種不同的作業系統;向我們需要的四個作業系統就是下面的幾個Global巨集變數:
Q_OS_OSX MAC OS X
Q_OS_IOS iOS
Q_OS_WIN Windows
Q_OS_ANDROID Android
至於操作模式是Release、Debug還是正式執行模式方面的巨集變數,則很可惜的QT並沒有提供,所以我們就需要自行用變數當作旗標來判斷;現在我們可以將程式改成如下:
clock.OpNow = clock.APP_; //APP_, DEBUG_, RELEASE_
clock.D_Current = QDir::current();
#ifdef Q_OS_MAC
if(clock.OpNow == clock.APP_)
clock.S_CurrentPath = clock.D_Current.path() + "/analogclock.app/Contents/";
//Debug/Release Development Mode
else{
clock.D_Current.cdUp();
clock.S_CurrentPath = clock.D_Current.path() + "/";
}
clock.S_OpPath = "";
clock.S_ResPath = "Resources/";
#endif
#ifdef Q_OS_WIN
clock.S_CurrentPath = clock.D_Current.path() + "/";
if(clock.OpNow == clock.DEBUG_)
//#ifdef Q_DEBUG
clock.S_OpPath = "debug/";
else if(clock.OpNow == clock.RELEASE_)
clock.S_OpPath = "release/";
else
clock.S_OpPath = "";
clock.S_ResPath = "Resources/";
#endif
#ifdef Q_OS_IOS
clock.S_CurrentPath = clock.D_Current.path() + "/";
clock.S_OpPath = "";
clock.S_ResPath = "resource/";
#endif
#ifdef Q_OS_ANDROID
clock.S_CurrentPath = clock.D_Current.path() + "/";
clock.S_OpPath = "";
clock.S_ResPath = "assets:/";
#endif
clock.S_AbsPath = clock.S_CurrentPath + clock.S_OpPath;
QDir::setCurrent(clock.S_AbsPath);
程式中取用資源檔的時候就用一致的寫法:
soundQuarter = new QSound(S_ResPath + "alarm.wav");
l 建置與執行
現在大功告成了,只是要注意在MAC OS X或Windows作業系統建置時,若為QT開發平台debug/release狀態下,記得最前端加入以下一行程式:
clock.OpNow = clock.DEBUG_; //APP_, DEBUG_, RELEASE_
要建置正式執行app則改為:
clock.OpNow = clock.APP_; //APP_, DEBUG_, RELEASE_
現在你可以以自動判斷所在的作業系統平台而自行設定與更動了!試試看吧!!
l 延伸應用及問題
基本上我們已經學會並建立了一定的架構來因應四種不同的作業系統平台,看起來也可以做出像樣的應用程式了,可是當你想要發行或放在Apple Store或Android Market,你就會發現還差一大步,那是還缺甚麼呢?
留言列表