1. 程式人生 > >Qt Quick的國際化和本地化

Qt Quick的國際化和本地化

 

國際化您的應用程式

以下部分描述了國際化QML原始碼的各個方面。如果您對應用程式中的所有使用者介面元件都遵循這些指南,則可以針對不同語言和本地文化約定(例如日期和數字的格式化方式)本地化應用程式的各個方面。

1.對所有Literal使用者介面字串使用qsTr()

可以使用qsTr(),qsTranslate(),qsTrId(),QT_TR_NOOP(),QT_TRANSLATE_NOOP()和QT_TRID_NOOP()函式標記QML中的字串進行轉換。標記字串的最常用方法是使用qsTr()函式。例如:

Text {
    id: txt1;
    text: qsTr("Back")
}

此程式碼使“Back”成為翻譯檔案中的關鍵條目。在執行時,翻譯系統會查詢關鍵字“Back”,然後獲取當前系統區域設定的相應翻譯值。結果返回到text屬性,使用者介面將顯示當前語言環境的“Back”的相應轉換。

2.為翻譯器新增上下文

使用者介面字串通常很短,因此您需要幫助翻譯文字的人理解文字的上下文。您可以在要翻譯的字串之前將原始碼中的上下文資訊新增為額外的描述性文字。這些額外的描述包含在提供給翻譯者的.ts翻譯檔案中。

注意: .ts檔案是包含源文字的XML檔案和翻譯文字的位置。更新的.ts檔案將轉換為二進位制轉換檔案,並作為最終應用程式的一部分包含在內。

在以下程式碼段中,該//:

行上的文字是翻譯者的主要註釋。

//~行上的文字是可選的額外資訊。文字的第一個單詞用作.ts檔案中XML元素的附加識別符號,因此請確保第一個單詞不是句子的一部分。例如,註釋“Context not related that that”將轉換為.ts檔案中的“<extra-Context>與此無關”。

lupdate_only{
SOURCES = *.qml \
          *.js \
          content/*.qml \
          content/*.js
}

3.消除相同文字的歧義

翻譯系統將使用者介面文字字串合併為唯一項。這種合併可以節省翻譯工作的人必須多次翻譯相同的文字。但是,在某些情況下,文字相同但含義不同。例如,在英語中,“後退”表示向後退一步,也表示與前面相對的物體部分。您需要告訴翻譯系統這兩個單獨的含義,以便翻譯人員可以建立兩個單獨的翻譯。

通過新增一些id文字作為qsTr()函式的第二個引數來區分相同的文字。

在下面的程式碼片段中,not front文字是一個id,用於區分“Back”文字和backstepping“Back”文字:

Text {
    id: txt1;
    // This user interface string is only used here
    //: The back of the object, not the front
    //~ Context Not related to back-stepping
    text: qsTr("Back");
}

4.用於%x將引數插入字串

不同的語言將單詞放在不同的順序中,因此通過連線單詞和資料來建立句子不是一個好主意。相反,用於%將引數插入字串。例如,下面的片段具有兩個數引數的字串%1%2。這些引數隨.arg()函式一起插入。

Text {
    id: txt1;
    // This user interface string is used only here
    //: The back of the object, not the front
    //~ Context Not related to back-stepping
    text: qsTr("Back", "not front");
}

%1引用第一個引數並%2引用第二個引數,因此該程式碼生成如下輸出:“File 2 of 3”。

5.使用%Lx使數字本地化

如果%L在指定引數時包含修改器,則會根據當前區域設定對數字進行本地化。例如,在以下程式碼段中,%L1表示根據當前所選語言環境(地理區域)的數字格式約定格式化第一個引數:

Text {
    text: qsTr("File %1 of %2").arg(counter).arg(total)
}

然後,用上面的程式碼,如果total是數字“4321.56”(四千三百二十一點五十六); 使用英文區域設定,(區域設定)輸出為“4,321.56”; 使用德國區域設定,輸出為“4.321,56”。

6.國際化日期,時間和貨幣

沒有用於格式化日期和時間的特殊字串修飾符。相反,您需要查詢當前區域設定(地理區域)並使用Date方法格式化字串。

Qt.locale()返回一個Locale物件,其中包含有關語言環境的各種資訊。特別是,Locale.name屬性包含當前語言環境的語言和國家/地區資訊。您可以按原樣使用該值,也可以對其進行解析以確定當前區域設定的相應內容。

以下程式碼段使用Date()獲取當前日期和時間,然後將其轉換為當前語言環境的字串。然後,它將日期字串插入%1引數以進行適當的轉換。

Text {
    text: qsTr("%L1").arg(total)
}

要確保貨幣號已本地化,請使用數字型別。此型別具有與日期型別類似的功能,用於將數字轉換為本地化貨幣字串。

7.對可翻譯資料文字字串使用QT_TR_NOOP()

如果使用者在不重新啟動的情況下更改系統語言,則系統可能無法自動重新整理陣列和列表模型中的字串以及其他資料結構。要在使用者介面中顯示文字時強制重新整理文字,您需要使用QT_TR_NOOP()巨集宣告字串。然後,當您填充要顯示的物件時,您需要顯式檢索每個文字的翻譯。例如:

Text {
    text: qsTr("Date %1").arg(Date().toLocaleString(Qt.locale()))
}

8.使用區域設定擴充套件本地化功能

如果您想要不同地理區域的不同圖形或音訊,可以使用Qt。locale()獲取當前的語言環境。然後為該區域設定選擇合適的圖形或音訊。

以下程式碼段顯示瞭如何選擇代表當前語言環境語言的相應圖示。

ListModel {
    id: myListModel;
    ListElement {
        //: Capital city of Finland
        name: QT_TR_NOOP("Helsinki");
        }
    }

...

Text {
    text: qsTr(myListModel.get(0).name); // get the translation of the name property in element 0
    }

9.準備動態語言更改

您可以通過使用QCoreApplication :: installTranslator()和QCoreApplication :: removeTranslator()新增和刪​​除轉換器來更改Qt轉換函式使用的語言。之後,您可以呼叫QQmlEngine :: retranslate()來觸發重新整理所有使用翻譯的繫結。因此,您的使用者介面將動態切換到新選擇的語言。

或者,您也可以將QEvent :: LanguageChange事件轉發到應用程式的QQmlEngine例項,或將您自己的訊號連線到QQmlEngine :: retranslate()。

本地化您的應用程式

Qt Quick應用程式使用與Qt C ++應用程式相同的底層本地化系統(lupdate,lrelease和.ts檔案)。您使用Qt語言學手冊中描述的相同工具。您甚至可以在同一個應用程式中使用C ++和QML源中的使用者介面字串。系統將建立單個組合翻譯檔案,並且可以從QML和C ++訪問字串。

使用條件隱藏編譯器中的QML源

lupdate工具從應用程式中提取使用者介面字串。lupdate讀取應用程式的.pro檔案,以識別哪些原始檔包含要翻譯的文字。這意味著您的原始檔必須列在.pro檔案的SOURCESHEADERS條目中。如果未列出您的檔案,則無法找到其中的文字。

但是,SOURCES變數適用於C ++原始檔。如果在那裡列出QML或JavaScript原始檔,編譯器會嘗試將它們構建為C ++檔案。作為一種變通方法,您可以使用lupdate_only{...}條件語句,以便lupdate工具檢視.qml檔案,但C ++編譯器會忽略它們。

例如,以下.pro檔案片段指定應用程式中的兩個.qml檔案。

Component.onCompleted: {
    switch (Qt.locale().name.substring(0,2)) {
        case "en":   // show the English-language icon
            languageIcon = "../images/language-icon_en.png";
            break;
        case "fi":   // show the Finnish language icon
            languageIcon = "../images/language-icon_fi.png";
            break;
        default:     // show a default language icon
            languageIcon = "../images/language-icon_default.png";
    }
}

您還可以使用萬用字元匹配指定.qml原始檔。搜尋不是遞迴的,因此您需要指定原始碼中存在使用者介面字串的每個目錄:

lupdate_only{
SOURCES = main.qml \
          MainPage.qml
}

有關Qt本地化的更多詳細資訊,請參閱Qt語言學手冊