Qtブログ(日本語)

Qt Quick多言語アプリの作り方

作成者: Mikio Hirai|Sep 10, 2024 4:46:37 AM

皆様、こんにちは。Qt Japanでソリューションエンジニアを務めている平井です。

今回は、Qt Quickで多言語アプリを作るやり方について、ステップバイステップで説明をするブログ記事を書いてみたいと思います。

このブログでカバーする範囲

  • lupdateやlrelease、Qt Linguistの使い方を学び、Qtのアプリを複数言語(日本語と英語)に対応するようにする
  • qsTr()とqsTrId()の使い方を学ぶ
  • 翻訳に必要なワークフローをCMakeで自動化する
  • 配列やモデルの文字列データをQT_TR_NOOP()やQT_TRID_NOOP()をつかって翻訳する

環境

以下が今回の環境です。

  • Windows 11
  • Qt 6.7.1 (msvc 2019キット)

プロジェクト作成

では早速、プロジェクト作成していきます。

Qtをインストールされている方は、お手元のQt Creatorを開いて、是非一緒にやっていきましょう。

Qtのインストールは、こちらから可能です。

まず、Qt Creatorを開き、ようこそ画面からのCreate Projectを押下します。

Application(Qt) > Qt Quickアプリケーション > 選択...を選択していきます。

プロジェクトパスでは、プロジェクトの名前を名前欄に、プロジェクトを配置するパスをパス欄に記述して次へ(N)を押下します。

プロジェクトの詳細定義では、特に何も変更せずに次へ(N)を押下します。

キットの選択ではDesktop Qt 6.7.1 MSVC2029 64-bitを選択します。

バージョン管理システムに追加(V)ではGitを選択しました。(これはやらなくても大丈夫です)

こうすると、.gitと.gitignoreを勝手にプロジェクトフォルダに作ってくれて便利です。
※ただし、Qt Creator 14.0.0現在、buildフォルダはデフォルトで生成される.gitignoreには含まれないので、必要な場合は手動で追加する必要があります。

プロジェクトの作成が完了すると、以下のような画面になります。

文字列の表示

多言語アプリを作るということで、早速文字列を表示していきます。

Qt Quickで一番シンプルな文字列は、Text QMLタイプを使用して表示できます。

上のように、Main.qmlのWindowの子要素としてTextを追加します。

textプロパティに、今回表示する文字列として"Hello World!"と設定し、anchors.centerInにはparentと設定しています。

anchors.centerInにparentを設定すると、自分の親要素(ここではWindow)の中央に自分自身を固定表示します。

この状態で左下の緑色のRunボタンを押下すると、プログラムがコンパイルされ、実行されます。

上のように、Windowの中央にとても小さいHello World!が表示されました。

翻訳作業に移る前に、流石にHello World!が小さすぎるので、少し大きめに変更したいと思います。

Qt Creatorでは、QMLタイプやプロパティをマウスでクリックした後にF1キーを押下すると、選択されたQMLタイプやプロパティのドキュメンテーションをIDE内で確認することができます。

ドキュメンテーションにフォーカスが当たっている状態でCtrl + Fを押すと、検索ボックスを表示することができます。

上のように、「size」で検索をかけるとfont.pixelSizeを見つけることができるので、クリックして詳細を確認しましょう。

文字列のピクセルサイズを指定できるプロパティのようです。

以下のように、font.pixelSize24と設定してアプリケーションを実行すると、実際Hello World!が大きくなりました。

多言語化してみる

では、文字列を1つ作れましたので、早速多言語化のワークフローを見ていきましょう。

本来のプロジェクトではもっと多くの文字列を作成してから翻訳、となるところでしょうが、今回はやり方を紹介するブログということで、1つの文字列で満足していったん多言語化してみます。

多言語化を行うには、QMLの専用のAPIで文字列を囲み「この文字列は翻訳対象ですよ」と示してあげる必要があります。

「QMLってなんですか」という疑問を持たれた方へ:QMLは、今まで書いてきたWindowTextなどのQMLコンポーネントと、その属性値(プロパティ)を記述することで、流動的なアニメーションをもつモダンなGUIを作成することができるQt独自のクロスプラットフォーム宣言型プログラミング言語です。

アニメーション画面遷移もQMLで実装できますし、JavaScriptも記述できます。

デスクトップアプリモバイルアプリWebアプリ組み込みアプリのGUIはQMLひとつ覚えておけば作成できるという優れものです!

QMLの宣伝はここまでにして、早速QMLの多言語APIを見ていきましょう!

qsTr()

qsTr()は、一番オーソドックスな多言語APIと言っても過言ではないでしょう。

使う際は、以下のように翻訳したい文字列を囲みます。ここで引数となる文字列は、元言語で記述(ここでは英語)された文字列になります。

この状態でアプリケーションを実行しても、とくに結果に変化はありません。

以下のスクリーンショットにあるように、元言語の"Hello World!"がそのまま表示されます。

これを翻訳するには、lupdateというコマンドラインツールを使用する必要があります。

lupdateは、Qtインストールディレクトリのbinフォルダに入っています。

lupdateを使ってプロジェクトをスキャンすると(方法は後述)、.tsファイルというファイルを生成してくれます。

.tsファイルはxmlの形式となっており、QMLファイル内でqsTr()などの多言語APIで囲まれた文字列をピックアップして収録しています。

まずは、.tsファイルを我々のMain.qmlから生成してみましょう。

その前に、プロジェクトフォルダにi18nという名前のフォルダを作成します。(このフォルダの中に.tsファイルを生成するかどうかは任意です)

今回はこのフォルダの中に、生成された.tsファイルを保存します。

Qt Creatorのターミナルか、コマンドプロンプトから、lupdateを実行していきます。

コマンドラインのオプション一覧はこちらのドキュメンテーションで確認できます。

以下のようにコマンドを実行すると、i18nフォルダにqml_ja_JP.tsが生成されます。

今回のコマンドでは「.qml拡張子のファイルをカレントディレクトリから再帰的にスキャンして、そこにあるqsTr()などのAPIで囲まれた文字列から.tsファイルをqml_ja_JP.tsという名前でi18nフォルダに作ってね」ということを行っています。

ちなみに、多言語のQMLアプリを作る際の.tsファイルの名前は、"qml_"で始まる必要があります

.tsファイルの末尾はISO-639の言語コード(小文字)とISO-3166の国コード(大文字)を使用できますので、今回は英語の原文に対して日本語の翻訳を作成するということでja_JPとしました。

結果的に、.tsファイルのファイル名は、qml_ja_JP.tsとなりました。

.tsファイルは、翻訳先の言語(もしくは+地域)ごとに作成します。今回は英語の原文に対して日本語の翻訳先という形なのでqml_ja_JP.tsのみを作成しましたが、例えば韓国語に対応する場合は、同様にqml_ko_KR.tsも作成することになります。

.tsファイルをお好みのテキストエディタで開いてみると、以下のように2つの文字列がしっかりとスキャンできていることが分かります。(よく見ると、ウィンドウのタイトルのHello WorldもさりげなくqsTr()で囲まれていたことに今気が付きした)

.tsファイルを普通のエディタで開いても見づらいので、Qt Linguistというツールを使用して.tsファイルの編集を行います。

Qt Linguistは、Qtインストールディレクトリのbinフォルダに入っています。

Qt Linguistを起動し、ファイル > 開く(O)...を押下します。

先程生成したqml_ja_JP.tsを選択して開くと、以下のような画面が表示されます。順を追って説明します。(参考:Qt Linguist user interface

 

コンテキストには、翻訳のコンテキストが表示されます。今回の例では、簡単に言うと、QMLファイル名です。今回はMain.qmlを使用していますので、Mainと表示されています。複数の.qmlファイルをlupdateでスキャンした場合は、こちらにそれぞれのファイル名が表示され、選択されたQMLファイルに属する文字列が右側の文字列に表示されます。

今回はMain.qmlに含まれる"Hello World"(タイトル部分)と"Hello World!"(テキスト部分)が表示されています。

ソーステキストを選択すると、そこに該当するQMLファイルの行が右側のソースとフォームでハイライトされます。

ソーステキストを選択すると、ソースとフォームで該当行がハイライトされる他に、下部分に翻訳語のテキストと翻訳者のコメントを記述する欄が表示されます。

早速、1つ目の、タイトルの"Hello World"から翻訳していきましょう。

以下のようにタイトルの"Hello World"を選択し、Translation to 日本語Translator comments for 日本語を埋めていきます。

翻訳が完了したソーステキストに関しては、左側に表示されている「?」をクリックして緑色のチェックマークに表示を変更します。

右上のセーブアイコンでここまでの変更をセーブすると、フレーズと推測にソースフレーズと翻訳、定義が表示されます。簡単に言うと、フレーズと推測には、原文と翻訳語のテキストのリストが表示されると考えてよいと思います。

続いて、2つめのテキストの"Hello World"を選択して同じように翻訳していきます。

すると、警告に「訳がソーステキストと同じ句読点で終わっていません。」と表示されました。

確かに、原文の"Hello World!"はビックリマーク(!)で終わっているのに対して、翻訳語の「ごきげんよう!世界」はそうはなっていません。この点を指摘されています。

Qt Linguistの検証(A)を開くと、どういった検証が行われているかを確認したり、検証ごとに有効化/無効化をすることができます。

翻訳の意図が間違っていなければ「ごきげんよう!世界」のままでも問題はないので、今回はこの警告を無視します。Hello World!の左に表示されているビックリマーク()をクリックして、黄色のチェックマークに変更しましょう。その後、変更をセーブします。

ところで、翻訳元の言葉によっては、同じ単語でも全く違う言葉に翻訳しなければならないケースがあり、翻訳者に誤解を与えないように明確に意図を伝える必要があります。

例えば、"Orange"という単語は、フルーツの「オレンジ」なのか、色の「オレンジ色」なのか、文字を見ただけでは判断がつきません。

そういった場合に誤解を避けるために、QMLのqsTr()などの翻訳用APIには便利機能が用意されています。それらを見ていきましょう。

翻訳者に対するコメントを利用することで、翻訳者がQt Linguist上でコメントを確認することができるようになります。

メインのコメントは//:からスタートすることで記述可能です。

実際に、以下のようにMain.qmlに翻訳者向けのコメントを追加してみましょう。

TextのHello Worldにも同じようにコメントを追記します。

ここまで出来たら、再度lupdateを実行してqml_ja_JP.tsファイルを更新します。

更新されたqml_ja_JP.tsを確認します。しかし、追加した翻訳者向けのコメントが表示されていないことにお気づきでしょうか...?

一方で、既存のqml_ja_JP.tsファイルを更新するのではなく、新規に別ファイル、例えばqml_updated_ja_JP.tsを生成すると、

以下のように、先程追記した翻訳者向けのコメントが表示されています。

この問題は、特に今回のように既に.tsファイルに翻訳語の文字列を入れた後に発生すると、手動で.tsファイルの翻訳語文字列をマージしなければならず、非常に面倒です。(そして、今回はその手段をとるしかありません...)

本件に関しては、R&Dに修正対応をしてもらうために、バグレポートを発行しました。

修正がされるまでは、翻訳者向けコメントはlupdateを実行する段階で記述しておくことを推奨します。

ということで、今回はqml_updated_ja_JP.tsにある翻訳者向けコメントをqml_ja_JP.tsに対して手動でマージ(コピー&ペースト)していきます。結果として、マージ後のqml_ja_JP.tsは以下のような形となります。

変更したqml_ja_JP.tsをQt Linguistで開くと、開発者向けのメインコメントが以下のように表示されました。翻訳者は、このコメントを見て開発側の文字列の意図を理解し、翻訳語の文字列を作成します。

 

翻訳者へのコメント以外にも、開発側の意図を翻訳者に伝えるための方法は存在します。

それは、同一の単語を翻訳する際の曖昧さ回避です。

qsTr()は第2引数を取ることができ、そこに曖昧さ回避のためのコメントを入れることができます。

上の例では、「Orange」という単語に対して、それぞれqsTr()の第二引数にコメントを追加することで曖昧さの回避を図っています。

ここまでの変更をしたら、再度lupdateを実行してqml_ja_JP.tsファイルを更新しましょう。

更新された.tsファイルをQt Linguistで開きます。

※この際に、一度Qt Linguistを閉じ、再度Qt Linguistを起動したうえで更新済みのqml_ja_JP.tsファイルをお開き下さい。(バグレポート:QTBUG-128603QTBUG-128604

すると、上のように開発者のコメントにqsTr()の第2引数で指定した曖昧さ回避のためのコメントが表示されました。

このコメントに従って、それぞれの「Orange」を翻訳していきます。

 

UIを多言語表示する

ここまでの翻訳作業が終了したら、qsTr()以外の翻訳APIをご紹介する前に、実際にGUI上で翻訳されたテキストを確認してみる作業に移ります。

現状、Qt Creatorでアプリケーションを実行すると、以下のように原文である英語での表示になると思います。

これを、システムロケールである日本語をQtアプリが自動的に参照して、日本語に翻訳されたUIを表示するようにしていきます。

ちなみに、この時点で私のWindowsのシステムロケールは日本語になっていますが、もし英語になっている場合は以下の手順を踏んでもUIは英語のままになりますので、ご注意ください!

まず、プロジェクトフォルダの直下にあるCMakeLists.txtを開きます。

以下のように、find_package()にLinguistToolsを追加してください。

上のスクリーンショットの吹き出しにあるように、LinguistToolsをfind_package()に追加すると、Qtアプリを多言語化する際に使用できる便利なcmake APIを使えるようになります。

次に、qt_standard_project_setup()I18N_TRANSLATED_LANGUAGES ja_JPを追加しています(上記スクリーンショット9行目)。

ここでは、原文が英語、翻訳先言語が日本語のみとなっているので、ja_JPのみを追加していますが、複数の翻訳先言語がある場合は、それらを半角スペース区切りで追加します。ざっくりいうと、.tsファイルで使っている言語コードと国コードのサフィックスをここに列挙するイメージです。

最後に、qt_add_translations()を以下のように追記します。

さて、ここまでを済ませると、CMakeLists.txtが更新されたことにより、自動的にcmakeの設定(コンフィグレーションとジェネレーション)が実行されたことと思います。

もし実際にcmakeの設定が実行されたかが怪しい方は、以下のようにQt Creator左側のプロジェクトからプロジェクト名を右クリックし、表示されるメニューからCMakeの実行をクリックしてcmakeの設定を実行しましょう。

 

cmakeによる設定が終了したら、Qt Creatorの左側のコラムにあるプロジェクトをクリックし、ビルドに使用しているキット(私の場合はDesktop Qt 6.7.1 MSVC2019 64bit)のビルドをクリックすると表示される右側のビルド設定から、ビルド ステップを展開します。

ターゲット:を下にスクロールすると、<プロジェクト名>_lrelease<プロジェクト名>_lupdateというターゲットがあると思いますので(私の場合はmulti_laungauge_lreleasemulti_language_lupdate)、それらのチェックボックスをONにします。

こうすることで、今まで手動で行っていたlupdateが、アプリケーションをビルドする際に自動的に実行されるようになります。

さらに、実はこれまで作成した.tsファイルは、lreleaseというコマンドラインツールを使用して.qmファイルというバイナリ形式に変換された上で、アプリケーションバイナリのリソースとしてリンクされるという必要があるのですが、その手順に関してもアプリケーションビルド時に自動的に行ってくれるようになります。

ですので、ここまでの手順が終了した状態でアプリケーションを実行すると、実際に実行時のコンピューターシステムのロケールをアプリケーションが参照して、それに応じた言語でUIを表示するようになります。

私の日本語ロケールのWindowsでは、アプリケーションを実行すると以下のように日本語のUIが表示されました。

ちなみに、Windowsの設定で言語を英語に変更すると、

以下のように、アプリケーションを実行すると英語のUIが表示されました。

動的な表示言語の変更

ここまでで、翻訳したUIをアプリケーションを実行時にシステムロケールによって変更する方法を学びました。

では、UIの表示言語をアプリケーションを実行中に切り替えるにはどうしたらよいのでしょうか?

実は、Qtでは簡単な方法が用意されています。

Qt.uiLanguageというグローバル変数をQML内で変えることで、表示言語を切り替えることができます。

試しに、Main.qmlに以下のコードを追加してみます。

Component.onCompleted: Qt.uiLanguage = "en"

ここで、Component.onCompletedは、コンポーネントの構築が完了した際に発生するイベントで、コロンの後に記述した処理がそのイベント発生時に実行されます。ここでは、Windowが構築されたタイミングでQt.uiLanguageを"en"に変更することで、アプリケーションが立ち上がった時にUIの表示言語が英語になるようにしています。

実際、この状態でアプリケーションを実行すると、システムロケールは日本語ですが、英語のUIが表示されました。

表示言語が動的に変更可能であることをもっとわかりやすくするために、ボタンを押下したらUI表示言語を日本語と英語で切り替えるようにしてみましょう。

まず、2行目でQtQuick.Controlsをインポートします。

こうすることで、29行目で使用しているButtonがファイル内で使えるようになります。

ここでは、textプロパティにqsTr()で囲んだ文字列を入れ、anchors.centerInを使用してWindowの中央に配置しています。

この時点でアプリケーションを実行すると、以下のような画面が表示されます。

さて、アプリケーションを実行する際にビルドも実行されたので、この際に先ほどCMakeでセットアップしたlupdateが自動的に実行され、i18nフォルダの中のqml_ja_JP.tsファイルが更新されました。Buttonのtextで使用している新しい文字列が追加されているはずです。

Qt Linguistを開きなおしたうえで、更新された.tsファイルを開き、Buttonの文字列も翻訳してしまいましょう。

Qt Linguistで更新したqml_ja_JP.tsをセーブしたのちアプリケーションを実行すると、以下のようにButtonの文字列も日本語として表示されます。

ここから、ボタンを押下したらUIの言語が切り替わるようにMain.qmlを変更していきます。

上記では、ButtonのonClickedイベントハンドラーを使用して、ボタンが押下されたときにQt.uiLanguageの値を確認し、もし"en"なら"ja_JP"をQt.uiLanguageに代入し、"en"でなければ"en"を代入するようにしています。

qsTrId()

読者の皆様の中には、多言語アプリを実装する際に、上記のようにオリジナルの文字列を元言語(今回の例では英語)で記述するのではなく、テキストのIDとして記述し、それに対応する英語や日本語の文字列を翻訳語の文字列として登録している方もいらっしゃると思います。

そういう場合は、qsTr()ではなく、qsTrId()を使用しましょう。

IDベースの多言語化アプリ作成に関して詳しく知りたい方は、公式ドキュメントをご覧ください。

先程のアプリを例にとって、IDベースの多言語化ワークフローを学んでいきます。

まずは、Main.qmlのqsTr()をすべてqsTrId()に変更します。

qsTr()とqsTrId()は併用できないので、アプリ内で使用するのは必ずどちらか片方にしましょう!

次に、qsTr()で曖昧さ回避のために使用していた第2引数を削除します。

qsTrId()では、意味の違う文字列はそれぞれ別のテキストIDとして管理するので、曖昧さ回避のためのコメントも不要になります。

次に、それぞれのテキストをテキストIDに変更します。

テキストIDの記述方法は開発チームによってまちまちだとは思いますが、今回はすべて小文字とし、文字とのつなぎはハイフンで区切ります。

この状態でアプリケーションを実行すると、文字列のIDがそのままUIに表示されます。

qsTrId()では、//%の後にテキストをダブルクォーテーションで囲って記述することで、そのテキストをQt Linguistのソーステキストとして扱うことができます。

上記のように、//%の後に英語での原文を記述します。

さらに、IDベースの多言語化の際には、CMakeLists.txtにも変更が必要になります。

まず、今回は英語での原文ではなく、文字列のIDをqsTrId()で使用するので

、英語で文字列を表示する際の文字列を登録するためのqml_en.tsも生成する必要があるので、qt_standard_project_setup()にenも追加します。こうすることで、qml_ja_JP.tsに加えて、qml_en.tsも生成されます。

そして、26行目でqt_add_translations()にLRELEASE_OPTIONS -idbasedを追加しています。これは、qsTrId()を使用する際に必要となるオプションです。

ここまで完了したら、一度以下のようにi18nフォルダにある.tsファイルの名前をバックアップ用に変更しましょう。qsTr()ベースのアプリケーションで使用していた.tsファイルをqsTrId()ベースのアプリケーションから生成された.tsファイルで上書きすることもできますが、そうすると現状は手動で.tsファイルを編集して調整を行う必要が出てくるため、今回は1からqsTrId()アプリ用の.tsファイルを生成します。

 

ここまでの変更をした上でアプリケーションを実行すると、以下のように//%で指定したテキストがUIに表示されます。

ここで、生成されたqml_ja_JP.tsファイルと、qml_en.tsファイルの内容を確認してみましょう。

開いてみると、<context>直下の<name>にコンテキスト名(ここではQMLファイル名なので、Main)が入っていないことが分かります(QTBUG-128617)。

こちらは手間ですが、手動でMainと入力していきましょう。
(※のちに調べた結果、qsTrId()でコンテキストが表示されないのは仕様だそうです。qsTrId()では、同じテキストは共通のidで管理するため、例えば複数のコンテキストに同じidを持つqsTrId()が散らばっていた場合に、同じidなのにも関わらず複数のコンテキスト上で表示され、それをすべてQt Linguistで翻訳する手間を考えると、一か所にまとまっていた方がよい、ということでしょうか。)

同様に、qml_en.tsに関しても手動で<context><name>にMainと入力していきます。

変更をセーブしたら、Qt Linguistで翻訳作業を行っていきます。

Qt Linguistを起動して、qml_ja_JP.tsを開きます。

qml_ja_JP.tsを開くと、上の方なダイアログが表示されたかと思います。

言語がJapanese(日本語)、国/地域がJapan(日本)となっていることを確認したら、OKを押下しましょう。

次に、qml_en.tsを開いていきます。qml_ja_JP.tsが開いている状態でファイルを開くを選択し、qml_en.tsをQt Linguistで開いていきます。

言語をEnglish、国/地域をAny Territoryとし、OKを押下しましょう。仮にqml_en_US.tsやqml_en_GB.tsなどの場合は、それぞれUnited StatesやUnited Kingdomとしていたところですが、今回は言語コードだけ(en)なので、Any Territoryとしました。

複数の翻訳先言語の.tsファイルを同時に開くことで、Qt Linguist上で同時に複数言語の翻訳データを入力することができます。

以下のように、翻訳語の文字列を埋めていきましょう。

Orangeの翻訳に関しては、qsTrId()の引数として"orange-color"としてはいるものの、翻訳者からの観点では少々わかりづらいので、//:のコメントで「これは色を意味している」ということを明確化したほうがいいな、と思いました。

ここまでの翻訳作業が完了したら、Qt Linguistでqml_ja_JP.tsとqml_en.tsを保存し、アプリケーションを再度実行してみましょう。(もし文字列IDが表示される場合は、.tsファイルが保存されているかを確認し、アプリケーションを再度ビルド&起動してみましょう)

上の様に、動的な翻訳がqsTrId()を使用して可能になりました。

 

配列やモデル内の文字列を翻訳する

最後に、リストのデータに翻訳対象の文字列を持つ場合についてご説明します。

QMLでは、ListModelListViewを使用して、データの内容と、それをどのような形式で表示するかを分離したソフトウェア構造を実装することができます

例えば、以下のようなQMLコードを記述すると、

ListModel内にそれぞれ定義されたデータが、delegateに定義された表現方法(緑色で24px)でリストとして表示されます。

さて、ここで、ListElementに定義されたデータを翻訳対象としたい場合はどうすべきでしょうか?

普通に考えると、単純にListElement内の文字列をqsTr()やqsTrId()などの翻訳APIで囲むのだろうと考えると思います。

しかし、Qtのドキュメンテーションによると、システムによっては、システムの言語設定変更後にユーザーが再起動を行わない場合は、配列モデルに含まれる翻訳文字列に関しては自動的に更新されない可能性があると記述されています。

これを避けるために、それらのモデルにデータとして定義されている文字列に対してはqsTr()とqsTrId()の代わりに、それぞれQT_TR_NOOP()QT_TRID_NOOP()を使用する必要があります。

※ちなみにこちらのドキュメンテーションでは、

  • qsTrNoOp()
  • qsTranslateNoOp()
  • qsTrIdNoOp()

と記述がありますが、これらのAPI名は誤植です!こちらで修正がされました。

ここまでを踏まえると、今回のケースでは以下のようにQMLのコードを記述する必要があるということになります。

ちなみに、アプリケーションを実行した結果生成されるqml_ja_JP.tsファイルには、以下のようにListElement内にある文字列がしっかりと翻訳対象文字列として登録されていることが分かります。

あとは、これまで通りの手順を踏んで翻訳後の文字列を作成してqml_ja_JP.tsファイルを更新すれば、多言語対応のされたQt Quickアプリケーションが作成できます!

 

おわりに

ここまでで、Qt Quickアプリを多言語化する際のステップをまとめました。いかがでしたでしょうか?

アプリケーションのi18n、l10nに関するさらに深いトピック、例えばRTL対応や文字切れチェックの自動化などは、以下の参考記事をご覧ください。