Qt5再入門: Qt DesignerでNotes C APIコンバートシミュレーターダイアログを作る(その13/翻訳機能2)
同(その12/翻訳機能1)の続きです。
No2. 対訳情報の作成/更新
準備
翻訳機能を使用するには、Qtプロジェクト(.pro)のTRANSLATIONS変数に翻訳ファイル名(.ts)を指定する必要があります。このファイル名は、翻訳したい文字列を抽出するツール(lupdate)で利用されます。
例えば、作成したい翻訳言語分の複数のファイル名を、以下のように指定することができます。
TRANSLATIONS += myapp_ja_JP.ts \
myapp_fr.ts \
myapp_de.ts
この例では、「myapp_」という接頭辞を共通にして、ja_JP(日本語)、fr(フランス語)、de(ドイツ語)のファイル名を指定しています。
これでlupdateツールを使うと、これら3つのファイルが作成、または更新されます。
作成/更新
初めて翻訳ファイルを作る時、または翻訳したい文字列が増えた/減った時にする作業で、以下の手順を取ります。
a. ソースコードから翻訳ファイルを抽出する
b. 翻訳ファイルに翻訳文字列を登録する
c. 翻訳ファイルをリリースしてバイナリファイルを作成する
aは、ソースコード中でtr関数やtranslate関数によってマークされているリテラル文字列を、翻訳ファイル(.ts)として作成/更新する作業です。これにlupdate コマンドを使用しますが、Qt Creatorにも組み込まれています。
bは、「Qt Linguist」というGUIツールを使って翻訳ファイル(.ts)を開き、ソースコード中の文字列に対訳を付ける作業です。
cについては、後述します。
3. 翻訳情報のリリース
残りのcですが、対訳が含まれた翻訳ファイル(.ts)からバイナリファイル(.qm)を「リリースする」という作業になります。これには lrelease コマンドを使用しますが、Qt Creator、Qt Linguistにも組み込まれています。
翻訳情報のバイナリファイルができれば、あとはソースコード中でQTranslatorオブジェクトでそのファイルを読み込むだけです。
4. 翻訳情報のインストール
リリース処理をしてバイナリ化した翻訳ファイル(.qm)は、QTranslatorクラスオブジェクトによって読み込まれ、QCoreApplicationオブジェクトにインストールされます。
以下に、システムロケールに準じて適切なファイルを読み込むコード上の準備を示します。
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
// 翻訳ファイルのインストール
QTranslator t;
t.load(QLocale(), "myapp", "_", "./translations", ".qm");
a.installTranslator(&t);
MainWindow w;
// ...
}
デフォルトのQLocaleオブジェクトが生成する、言語と国の情報を元にした文字列(日本語ならja_JP)と、接頭辞、セパレータ、ディレクトリ、拡張子を用いてパスを生成し、そのファイルを読み込みます。
例えば、上記の例を日本語がデフォルトのOS上で実行した場合、以下のファイルを読み込もうとします。
./translations/myapp_ja_JP.qm
このときのカレントディレクトリはアプリケーションと同じになります。また、ファイルが見つからなかった場合は読み込みをあきらめるので、コード中の英語がそのまま使用されることになります。
このような読み込み形式を取った場合、OSに適用されている言語パックなどを元に、臨機応変に翻訳ファイルを切り替えることができます。
Qtリソースファイルの利用
Qtリソースファイル(.qrc)は単純なXMLファイルで、プラットフォームに依存せずに、アプリケーションの実行ファイルにバイナリファイルを格納するための仕組みです。例えば、アイコンや画像、音声などのファイルがそうですが、バイナリ化した翻訳ファイル(.qm)も、よくQtリソースに登録して使用します。
a. Qtリソースファイルを作成する
b. 翻訳ファイル(.qm)をリソースに登録する
c. ビルドして実行ファイルにファイルを取り込む
d. Qtリソースファイル用のパスを用いて、ファイルにアクセスする
アプリケーション内に取り込まれたファイルにアクセスするには、「:(コロン)」から始まるパス形式を指定します(後述)。
Qt翻訳機能を使った作業の流れ
ここまでの流れを動画で確認していただきますが、動画の中で使用しているUIと、翻訳に関わるソースコードを抜粋しておきます。
テキスト入力のラベルには「&Text」と入力しています。
次にスピンボックスのラベルには「&Number」と入力しています。
日時入力のラベルには「&Date/Time」と入力しています。
最後に、ボタンラベルには「&Current time」と入力しています。
なお、ここまで紹介したラベルには、すべてtr関数が適用されます。後述する動画にて確認できます。
次にソースコードを確認します。
// main.cpp
#include "mainwindow.h"
#include <QApplication>
#include <QTranslator>
#include <QLocale>
int main(int argc, char *argv[])
{
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication a(argc, argv);
// 翻訳ファイルのインストール
QTranslator t;
t.load(QLocale(), "notesexplorer3", "_", ":/translations", ".qm");
a.installTranslator(&t);
MainWindow w;
w.show();
return a.exec();
}
ディレクトリの指定に「:/translations」とコロンから始めているので、QtはQtリソースファイル中から該当するパスのファイルを検索します。
// convertsimulatatordialog.h
// ダイアログクラスのクラス定義(抜粋)
public slots:
void writeCurrentTime();
// convertsimulatordialog.cpp
// ダイアログクラスのコンストラクタ(一部)
connect(ui->currentTimeButton, &QPushButton::clicked,
this, &ConvertSimulatorDialog::writeCurrentTime);
// 追加したスロット関数
void ConvertSimulatorDialog::writeCurrentTime() {
ui->consoleLog->append(
tr("The current time is %1.")
.arg(QTime::currentTime().toString("HH:mm:ss"))
);
}
ボタンをクリックすると、テキストブラウザconsoleLogに、現在の時刻についてのメッセージが追加されます。このメッセージが、翻訳対象となるようにtr関数で囲っています。
これを踏まえて、動画をご覧ください。
まとめ
ここまでの翻訳作業について、簡単にまとめます。
Qtが持つ翻訳機能を、ほんのさわりだけご紹介しました。いったん設定などが済んでしまえば、あとは更新→翻訳→リリースを定型的にこなすだけなので、開発作業への支障はほとんどないと思います。
個人的には、下手にソースコード中にリテラルで日本語を書きたいと思わず、Google翻訳などを活用しながらQt翻訳で日本語化した方が、マルチプラットフォーム開発する上でも、あとあと手間がなくていいなと思っています。