2010年10月25日 星期一

Qt多國語言機制

Qt原本就內建了一套多國語言的機制,可是需要用到Qt Linguist。另外如果要作到動態的話,使用Qt Designer建立的GUI才有提供,要不然只能手動設定(參考)。

所以我自己改寫了一個class Translator。
為了使用方便,我利用了Singleton Pattern
只要傳入物件的指標,還有屬性,以及字串標籤。其他的部份,Translator都幫你處理了。
使用範例如下:
    QMenu *menu = new QMenu;
    menuBar()->addMenu(menu);
    Translator::add(menu, "title", "FILE");
    QAction *action = new QAction(0);
    menu->addAction(action);
    Translator::add(action, "text", "EXIT");
當然還有語言清單
menuBar()->addMenu(Translator::menu);

在這裡說明一下,我是利用Qt的setProperty來達到這個效果的。
bool QObject::setProperty ( const char * name, const QVariant & value )
只要是繼承至QOject的元件,都可以用setProperty來設定屬性值。
widget->setProperty("windowTitle", QVariant("標題"));

另外語言表方面,我比較喜歡用table而不是跟Qt一樣用list。table格式我選用csv,因為可以直接用openoffice編輯。
以下是csv檔的內容
"LANGUAGE_COUNTRY","en","zh_TW","zh_CN","ja","es"
"LANGUAGE_COUNTRY","English","繁體中文","简体中文","日本語","español"
"LANGUAGE","Language","語系","语言","言語","Lenguaje"
"FILE","File","檔案","文件","ファイル","Archivo"
"NEW","New","開新檔案","新建","新規","Nuevo"
利用第二列產生QMenu,
至於第一列則因為當要判斷作業系統環境時,需要用到language_country code

為什麼不跟Qt一樣,用英文當key,要用第一行的tag呢?
其實原因很簡單。當你有一天,發現老闆總是同一段英文一直換寫法,你就知道為什麼了。。。

2010年10月18日 星期一

license header template (Qt creator)

大部分的程式開頭,都有一段宣告。像是LGPL、GPL或doxygen的註譯等。
Qt creator提供一個license template的功能,當每次增加新的檔案時,都會在文件最前面加上設定好的字串。
Tools > Options... > C++ > License Template > Browse
選擇文件檔(像是gpl.txt)

以下Qt提供的特殊placeholders

  1. %YEAR%: Year
  2. %DATE%: Date
  3. %USER%: User name
  4. %FILENAME%: File name
  5. %CLASS%: Class name (if applicable)
舉個例子:
/**
* @file %FILENAME%
* @brief define %CLASS% class
*
* Define %CLASS% class.
*
* @author %USER%
*
* @date %DATE%
*/
經過Qt轉換後,就會變成
/**
* @file dictionary.h
* @brief define Dictionary class
*
* Define Dictionary class.
*
* @author http://yycking.blogspot.com/
*
* @date 2010/10/18
*/

2010年10月3日 星期日

DPInst & nsis

DPInst是驅動程式安裝架構DIFx(Driver Install Frameworks) 所提供的工具之ㄧ。使用方式很簡單。
以下說明是以FTDI的driver為例:
  1. 將ftdi的driver解壓縮到driver資料夾
  2. 到微軟下載wdk
  3. 安裝完wdk後,可在WinDDK\redist\DIFx\dpinst中看到二個資料夾MultiLin(提供多國語言),EngMui(提供特定語言,預設為英文,除非提供.mui檔)
  4. 在MultiLin提供三個資料夾x86,amd64,ia64
  5. 將x86內的dpinst.exe重新命名為x86.exe,將amd64內的dpinst.exe重新命名為x64.exe。將x86.exe和x64.exe複製到driver資料夾(現在執行x86或x64就會幫你安裝FTDI的driver了)
  6. 因為我想要安裝程式時,偷偷的替user安裝驅動(也就是不用秀出DPInst的視窗)。
  7. 所以在driver的資料夾建立一個dpinst.xml檔。
    <?xml version="1.0"?>
    <dpInst>
    <!--- 不秀出視窗 -->
    <suppressWizard/>
    <quietInstallStrict/>
    <!--- 強迫安裝 -->
    <forceIfDriverIsNotBetter/>
    </dpInst>
    
  8. 在nsis中加入下面程式,即可自動判斷安裝32還是64位元的驅動
    ; Check OS is 32bit or 64bit
    !include "x64.nsh"
    !define FTDI_32_URL "$INSTDIR\driver\x86.exe"
    !define FTDI_64_URL "$INSTDIR\driver\x64.exe"
    
    Function installFTDI
    ${If} ${RunningX64}
    StrCpy $2 ${FTDI_64_URL}
    ${Else}
    StrCpy $2 ${FTDI_32_URL}
    ${EndIf}
    ExecWait $2
    FunctionEnd