ホーム · 全ての名前空間 · 全てのクラス · メインのクラス · グループ別 · Modules · 関数一覧

Qt の国際化

アプリケーションの国際化は、アプリケーションの作成された言語以外でアプリケーションを使用しやすいようにするプロセスです。

いくつかの場合、国際化は簡単です、例えば、米国のアプリケーションを豪州人や英国人が利用しやすくするにはいくつかのスペル修正で済むでしょう。しかし米国のアプリケーションを日本人が使いやすくしたり、韓国語のアプリケーションを独逸人に使いやすくしたりするのは言語の違いだけでなく入力の方法、文字エンコーディングや表示変換なども変更しなくてはなりません。

Qtは国際化をできるだけ開発者にとって苦痛のないようにしようとします。Qtにおいて、全てのサポートされた言語で、入力ウィジェットとテキスト描画法は標準装備を提供します。ビルトインフォントエンジンは同時に、さまざまな異なった書記体系からキャラクタを含むテキストを正しく魅力的に表すことができます。

Qtは今日、使用中のほとんどの言語をサポートします、特に:

Windows、 FontConfig(クライアントサイドのフォントサポート)を使用するUnix/X11、 Qt for Embedded Linux では次の言語もサポートされています:

これらのwriting systemsの多くに特殊な特徴が存在します:

Qt は上記の特別な機能の全てを考慮するよう努めます。あなたはQtの入力ウィジェット(例えば QLineEdit, QTextEditや派生クラス) や Qt の表示ウィジェット(例えば QLabel) を利用する上で、これらの特徴について通常は気に掛ける必要はない。

これらの記法のサポートはプログラマから見て透過的であり、 Qt's text engineに完全にカプセル化されている. 以下の小さな点を除いては、特定の言語で使われる記法に関して知っておく必要はない:

以下のセクションでは Qt がサポートする国際化 (i18n) の状況に関する情報を扱う. Qt Linguist manualも参照のこと.

段階的に

Qt を使ってクロスプラットフォームの国際化されたソフトウェアを書くには、簡単かつ緩やかなプロセスを踏む. 以下のステージを辿ることでソフトウェアを国際化することができる:

ユーザが目にする全てのテキストに QString を使用する

QString は内部的に Unicode 4.0 のエンコードを使っていることから、世界中の言語を理解しやすいテキスト処理操作で透過的に処理することができる. ユーザにテキストを表示する全ての Qt の関数では、その引数に QString を取るようになっており、 char * QString に変換するオーバーヘッドなどは生じない.

"プログラム領域" にある文字列 ( QObject の名前や、ファイルフォーマットのテキストなど) では QStringを使う必要はなく、プリミティブな char * QByteArray クラスで十分である.

あえて Unicode を利用していると意識する必要はなく、 QString QChar は、プリミティブな C 言語での const char * をより簡単にしたものとして利用できる.

全てのリテラル文字に tr() を使用する

ユーザが目にする "クォートで囲まれたテキスト" をプログラム中に書く場合には、それらが QCoreApplication::translate() 関数で処理される必要がある. 実際には、これは QObject::tr() を使うことでおこなう. たとえば、 LoginWidget QWidget のサブクラスであるとすると:

 LoginWidget::LoginWidget()
 {
     QLabel *label = new QLabel(tr("Password:"));
     ...
 }

This accounts for 99% of the user-visible strings you're likely to write.

クォートされたテキストが QObject サブクラスのメンバ関数内にない場合は、適当なクラスの tr() 関数を使うか、直接 QCoreApplication::translate() 関数を用いること:

 void some_global_function(LoginWidget *logwid)
 {
     QLabel *label = new QLabel(
                 LoginWidget::tr("Password:"), logwid);
 }
 void same_global_function(LoginWidget *logwid)
 {
     QLabel *label = new QLabel(
                 qApp->translate("LoginWidget", "Password:"), logwid);
 }

翻訳対象となるテキストが完全に関数の外となる場合には、2つのマクロ QT_TR_NOOP() と QT_TRANSLATE_NOOP() がその助けとなる. これらのマクロでは、テキストが以下で説明する lupdate ユーティリティによって摘出されるよう、単純に印を付けるだけにすぎない. マクロはテキストのみを処理対象として扱う (コンテキストは処理されない).

QT_TR_NOOP() の例:

 QString FriendlyConversation::greeting(int type)
 {
     static const char *greeting_strings[] = {
         QT_TR_NOOP("Hello"),
         QT_TR_NOOP("Goodbye")
     };
     return tr(greeting_strings[type]);
 }

QT_TRANSLATE_NOOP() の例:

 static const char *greeting_strings[] = {
     QT_TRANSLATE_NOOP("FriendlyConversation", "Hello"),
     QT_TRANSLATE_NOOP("FriendlyConversation", "Goodbye")
 };
 QString FriendlyConversation::greeting(int type)
 {
     return tr(greeting_strings[type]);
 }
 QString global_greeting(int type)
 {
     return qApp->translate("FriendlyConversation",
                            greeting_strings[type]);
 }

マクロ QT_NO_CAST_ASCII を定義して、 const char * から QString への自動変換を無効にした状態でソフトウェアをコンパイルすると、 QT_NO_CAST_FROM_ASCII 文字列の見落としを検出しやすくなる. 詳細については QString::fromLatin1() を参照されたい. ただし変換を無効にすることで、プログラミングが若干煩わしくなる.

ソースコードを Latin1 以外の文字を使って記述する場合には、 QObject::trUtf8 QObject::trよりも便利でtr() は QTextCodec::codecForTr() に依存して動作するので、 QObject::trUtf8() よりも壊れやすいという側面がある.

アクセラレータの値に QKeySequence() を使用する

Ctrl+Q や Alt+F といったアクセラレータの値も翻訳される必要がある. アプリケーションで Qt::CTRL + Qt::Key_Q が "quit" となるようにハードコードしてしまうと、トランスレータがオーバーライドできなくなってしまう. 正しい実装は以下のようにする

     exitAct = new QAction(tr("E&xit"), this);
     exitAct->setShortcut(tr("Ctrl+Q"));

動的なテキストに QString::arg() を使用する

QString::arg() 関数を使えば、引数の置き換えを簡単におこなえる:

 void FileCopier::showProgress(int done, int total,
                               const QString ¤tFile)
 {
     label.setText(tr("%1 of %2 files copied.\nCopying: %3")
                   .arg(done)
                   .arg(total)
                   .arg(currentFile));
 }

In some languages the order of arguments may need to change, and this can easily be achieved by changing the order of the % arguments. For example:

 QString s1 = "%1 of %2 files copied. Copying: %3";
 QString s2 = "Kopierer nu %3. Av totalt %2 filer er %1 kopiert.";
 qDebug() << s1.arg(5).arg(10).arg("somefile.txt");
 qDebug() << s2.arg(5).arg(10).arg("somefile.txt");

これで英語からノルウェー語への変換を正しくおこなうことができる:

 5 of 10 files copied. Copying: somefile.txt
 Kopierer nu somefile.txt. Av totalt 10 filer er 5 kopiert.

訳文を用意する

アプリケーションの隅々にいたるまで tr() の適用が終われば、プログラム内にあるユーザが目にするテキストの翻訳に着手することができる.

Qt Linguist マニュアル には Qt の翻訳ツールである Qt Linguist, lupdate および lreleaseに関する詳細な情報が載っている.

Qt アプリケーションの翻訳は3つのステップのプロセスからなる:

  1. lupdate を実行することで Qt アプリケーションの C++ ソースコードから翻訳対象となるテキストを抽出し、トランスレータに読み込ませるためのメッセージファイル ( .ts ファイル) を生成する. このユーティリティプログラムは上で説明した tr() と QT_TR*_NOOP() マクロを認識し、 .ts ファイルを (通常言語毎に) 生成する.
  2. .ts Qt Linguistを用い、.ts ファイル中のソーステキストに対する訳文を提供する. .ts ファイルは XML フォーマットで記述されているので、手で書き換えることもできる.
  3. lrelease を実行して .qm ファイルから実際の利用に適した軽量のメッセージファイル ( .ts )を生成する。 .ts ファイルは "ソースファイル" であり、 .qm ファイルは "オブジェクトファイル" に相当すると考えると判りやすい. 翻訳者は .ts ファイルを編集するが、アプリケーションの利用者は .qm ファイルのみを必要とする. どちらの種類のファイルもプラットフォーム独立であり、特定のロケールに依存するようなこともない.

一般に、アプリケーションのリリース毎にこれらのステップを踏むことになる. lupdate ユーティリティは以前のリリースからの翻訳を再使用しやすくなっている.

lupdate を実行する前に、プロジェクトファイルを用意しなければならない. プロジェクトファイル (.pro ファイル) の例を次に挙げる:

 HEADERS         = funnydialog.h \
                   wackywidget.h
 SOURCES         = funnydialog.cpp \
                   main.cpp \
                   wackywidget.cpp
 FORMS           = fancybox.ui
 TRANSLATIONS    = superapp_dk.ts \
                   superapp_fi.ts \
                   superapp_no.ts \
                   superapp_se.ts

lupdate または lreleaseを実行するときは、コマンドラインの引数としてプロジェクトファイルの名前を与える必要がある.

この例では、4つの外国語がサポートされている: デンマーク語, フィンランド語, ノルウェー語 そして スウェーデン語. qmakeを利用する場合には、通常 lupdateに関する別のプロジェクトファイルを用意する必要はない. qmake のプロジェクトファイルに TRANSLATIONS エントリを追加してやれば、上手く動作するはずだ.

アプリケーション側では、 QTranslator::load() で言語に合致した翻訳ファイルを読み込み、 QCoreApplication::installTranslatorを使ってインストールする必要がある.

linguist, lupdate および lrelease は Qt のインストールされたベースディレクトリの下の bin にインストールされる。ユーザーマニュアルを見るには Qt Linguist の Help|Manual をクリックすること. マニュアルにはチュートリアルが掲載されている.

Qt itself contains over 400 strings that will also need to be translated into the languages that you are targeting. You will find translation files for French, German and Simplified Chinese in $QTDIR/translations, as well as a template for translating to other languages. (This directory also contains some additional unsupported translations which may be useful.)

一般に、アプリケーションの main() 関数は以下のようになる:

 int main(int argc, char *argv[])
 {
     QApplication app(argc, argv);
     QTranslator qtTranslator;
     qtTranslator.load("qt_" + QLocale::system().name(),
             QLibraryInfo::location(QLibraryInfo::TranslationsPath));
     app.installTranslator(&qtTranslator);
     QTranslator myappTranslator;
     myappTranslator.load("myapp_" + QLocale::system().name());
     app.installTranslator(&myappTranslator);
     ...
     return app.exec();
 }

Note the use of QLibraryInfo::location() to locate the Qt translations. Developers should request the path to the translations at run-time by passing QLibraryInfo::TranslationsPath to this function instead of using the QTDIR environment variable in their applications.

エンコードのサポート

QTextCodec クラスと QTextStream の機能を使うことで、ユーザのデータを入出力する際に利用される多数のエンコードを容易にサポートすることができる. アプリケーションの起動後、フォントの選択・テキストの表示・8ビットのテキスト入出力・文字入力などで8ビットのデータが取り扱われた場合には、マシンのロケールとして8ビットエンコードが使われていると判断する.

アプリケーションは時としてデフォルトのローカルな8ビットエンコード以外のエンコードを必要とすることがある. たとえば、キリル文字の KOI8-R ロケール (ロシアにおけるデファクトスタンダードのロケール) で動くアプリケーションでは、キリル文字を出力するのに ISO 8859-5 エンコードでおこなう場合がある. これを実現するコードとしては次のとおり:

 QString string = ...; // some Unicode text
 QTextCodec *codec = QTextCodec::codecForName("ISO 8859-5");
 QByteArray encodedString = codec->fromUnicode(string);

Unicode をローカルな8ビットエンコードに変換する場合、ショートカットが利用できる: QString::toLocal8Bit() 関数はそうした8ビットデータを返す. ほかの便利なショートカットには QString::toUtf8() があり、これはテキストを8ビットの UTF-8 エンコードで返す. このエンコードは Unicode の情報を完全に保ちつつ、テキストが完全に ASCII コードで書かれている場合には、素の ASCII 文字列であるように見える.

他の変換方法としては、 QString::fromUtf8() と QString::fromLocal8Bit() の変換関数を使うか、一般的なコードを使う方法がある. 後者の方法を使って ISO 8859-5 のキリル文字から Unicode へ変換する例を挙げる:

 QByteArray encodedString = ...; // some ISO 8859-5 encoded text
 QTextCodec *codec = QTextCodec::codecForName("ISO 8859-5");
 QString string = codec->toUnicode(encodedString);

世界中のユーザ間でドキュメントのポータビリティを最大化できることから、理想的には Unicode の入出力が使われるべきであるが、実際にはユーザが既存ドキュメントを処理するうえで必要となる適切な全てのエンコードをサポートするのが望まれる. 一般的に、Unicode (UTF-16 または UTF-8) は任意の人々との間で情報伝送を行う場合に最適であり、対して一つの言語または国家グループの中で閉じるのであれば、ローカルな標準を使ったほうが適切であるといえる. 最も重要なエンコードは QTextCodec::codecForLocale() で返されるものであり、これはユーザが他の人々およびアプリケーションと通信するのに必要となるものである. (これは local8Bit() で使われるコーデック )

Qt は頻繁に利用されるエンコーディングの大部分をネイティブにサポートする. サポートされるエンコードの完全なリストは QTextCodec のドキュメントを参照のこと.

使用される頻度の低いエンコードなどでは、ユーザは独自の QTextCodec のサブクラスを作成する必要があるかもしれません。緊急の場合は既に誰かがそのエンコーディングのサポートを行っている可能性があるので、Qt のテクニカルサポートチームや qt-interest メーリングリストに質問をしてみるとよいかもしれません。

ローカライズ

ローカライズとはローカルな習慣へ適合させるプロセスのことでああり、たとえばローカルでよく使われるフォーマットで日時を表示したりすることである. 適切な tr() 文字列を使うことでローカライズをおこなうことができる.

 void Clock::setTime(const QTime &time)
 {
     if (tr("AMPM") == "AMPM") {
         // 12時間表示
     } else {
         // 24時間表示
     }
 }

この例では、US 向けには "AMPM" の翻訳をそのまま残すことで 12時間制の時刻表示を使い、ヨーロッパで向けでは何か別のものに翻訳することで24時間制の時刻表示を使うようにするといった使い方ができる.

数字をローカライズする場合には QLocale クラスを使うこと.

画像をローカライズすることは推奨されない. ある地域でしか使われない表現や判りにくい比喩表現を使ったりせず、全てのロケールで受け入れられる明瞭なアイコンを使うこと. 例外としては、アラビア語とヘブライ語のロケールでは画像の左右の矢印を逆にしなければならない場合がある.

動的翻訳

Some applications, such as Qt Linguist, must be able to support changes to the user's language settings while they are still running. To make widgets aware of changes to the installed QTranslators, reimplement the widget's changeEvent() function to check whether the event is a LanguageChange event, and update the text displayed by widgets using the tr() function in the usual way. For example:

 void QWidget::changeEvent(QEvent *event)
 {
     if (e->type() == QEvent::LanguageChange) {
         titleLabel->setText(tr("Document Title"));
         ...
         okPushButton->setText(tr("&OK"));
     } else
         QWidget::changeEvent(event);
 }

All other change events should be passed on by calling the default implementation of the function.

The list of installed translators might change in reaction to a LocaleChange event, or the application might provide a user interface that allows the user to change the current application language.

The default event handler for QWidget subclasses responds to the QEvent::LanguageChange event, and will call this function when necessary; other application components can also force widgets to update themselves by posting the LanguageChange event to them.

Translating Non-Qt Classes

It is sometimes necessary to provide internationalization support for strings used in classes that do not inherit QObject or use the Q_OBJECT macro to enable translation features. Since Qt translates strings at run-time based on the class they are associated with and lupdate looks for translatable strings in the source code, non-Qt classes must use mechanisms that also provide this information.

One way to do this is to add translation support to a non-Qt class using the Q_DECLARE_TR_FUNCTIONS() macro; for example:

 class MyClass
 {
     Q_DECLARE_TR_FUNCTIONS(MyClass)
 public:
     MyClass();
     ...
 };

This provides the class with tr() functions that can be used to translate strings associated with the class, and makes it possible for lupdate to find translatable strings in the source code.

Alternatively, the QCoreApplication::translate() function can be called with a specific context, and this will be recognized by lupdate and Qt Linguist.

システムのサポート

Qt の動作するオペレーションシステムおよびウィンドウシステムの中には、限定的な Unicode サポートしか提供されないものもある. 一般に Qt アプリケーションはプラットフォーム特有の制限にそれほど左右されることはないが、システム側で利用できるサポートの程度の差によっては Qt がそのプラットフォーム上で提供できるサポートに影響を及ぼす場合もある.

Unix/X11

Windows

Mac OS X

For details on Mac-specific translation, refer to the Qt/Mac Specific Issues document hereの Unicode オプションによって、ファイル入出力はデフォルトでローカルな8ビットエンコードになる.

関連する Qt のクラス

これらは Qt アプリケーションを国際化するのに関連するクラスである.

QInputContextデータとコンポージングステートに依存した入力メソッドの抽象化
QLocale数字と様々な言語における文字列表現との間の変換
QSystemLocaleユーザーのシステムロケールを調整するのに使用できる
QTextCodecテキストエンコード間の変換
QTextDecoderステートベースのデコーダ
QTextEncoderステートベースのエンコーダ
QTranslatorテキスト出力の国際化サポート


Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies) Trademarks
Qt 4.5.0