アプリ・ソフトをPySideで開発する時。
- グローバルなソフトを作りたい、
- 日本語以外の多言語に翻訳したい、
- 最低限 英語だけにも対応したい
そういう時はQTranslatorを使います。
ただその手順が思いのほかに難しかったです。
そこでここでは 英語 => 日本語 のように、
PySideソフトを多言語化する手順を解説します。
※ 開発にはPySide6を使用
このページの目次
1.pythonコード内で翻訳文字列をtr()で囲む
翻訳文字列を tr() で囲みます。
▼ QObject.tr()について
PySide6.QtCore.QObject.tr(sourceText[, disambiguation=None[, n=-1]])
PARAMETERS
- sourceText - str
- disambiguation - str
- n - intRETURN TYPE
str
リファレンスでの言及はこれだけ。
第1引数が翻訳対象の文字列です。また翻訳言語に対応するものがなかった場合に返されるデフォルトの値でもあります。このデフォルトは英語(en)にするのが無難。
日本語だとデフォでja_JPになっちゃいます。
▼ 実際には次のようなコードで翻訳する
1 2 3 4 5 6 7 8 9 10 |
from PySide6.QtCore import QObject, QTranslator, QLocale class App(QObject): def __init__(self): ## 翻訳文字列 msg = QObject.tr("Select a image file") print("msg : "+msg) if __name__ == "__main__": app = App() |
上記のようにpythonコード内で QObject.tr("Select a image file") と文字列を囲んでいくだけです。ひたすら翻訳対象を tr() していってください。
2.lupdateコマンドからtsファイルを生成
次にpyコードからtsファイルを作ります。
これはバイナリのqmファイルの材料みたいなもの
その生成に使うのが pyside6-lupdateコマンド です。
▼ 例えば次のようにコマンド実行
1 |
> pyside6-lupdate app.py -ts app.ja_JP.ts |
▼ 生成されたapp.ja_JP.tsの中身
1 2 3 4 5 6 7 8 9 10 11 12 |
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> <TS version="2.1" language="ja_JP"> <context> <name>QObject</name> <message> <location filename="launcher.py" line="232"/> <source>Select a image file</source> <translation type="unfinished"></translation> </message> </context> </TS> |
ご覧の通り普通のXMLファイルです。
3.linguistを使ってtsファイルの文字列翻訳
そしたら次にLinguistを使っての翻訳作業
GUIを使って翻訳できるので、この部分は楽です。
▼ 生成したtsファイルをLinguistをコマンドから起動
1 |
>pyside6-linguist app.ja_JP.ts |
▼ GUIが起動したら翻訳していけばOK
翻訳が終わったらtsファイルを一旦保存します。
4.lreleaseを使って .ts → .qm に変換する
そして翻訳が終わったらqmファイルとして保存します。
※ このqmはバイナリ形式
それにはlreleaseコマンドというもので変換可能です。
▼ 例えば以下のように変換する
1 |
pyside6-lrelease app.ja_JP.ts -qm translations/app.ja_JP.qm |
場所は pyside6-lrelease を実行した場所に translations という名前のフォルダを作り、そこに app.ja_JP.qm のファイル名で保存しました。
このqmファイルは命名規則を決めておくべきです。
ここでは上記のように名前を付けました。
qmファイル名 : app.ja_JP.qm
何でもいいですが、次の独自ルールにしてます。
- app.py の翻訳なら接頭辞は app にする
- 名前・言語コードはドット(.)で区切る
- 拡張子は必ず .qm にすること
後述するようにqmファイル読み込みは少し厄介です。
だから独自でも何でも命名規則を決めておくのがグッド
ここでは以上のようにして命名しました。
5.QTranslatorからqmファイルを読んで翻訳
いよいよ翻訳作業も大詰め
翻訳をQTranslatorから行ってみます。
▼ 次のようなpythonコードで試してみた
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
from PySide6.QtCore import QObject, QTranslator, QLocale class App(QObject): def __init__(self): ## 翻訳用qmファイルを読み込み translator = QTranslator(app) # qmファイルのあるディレクトリパス path = "/path/to/translations" if translator.load(QLocale.system(), 'app', '.', path): ## ローカルからqmファイル読み込み app.installTranslator(translator) translator = QTranslator(app) path = ':/translations' if translator.load(QLocale.system(), 'app', '_', './translations'): ## リソースからqmファイル読み込み app.installTranslator(translator) ## 翻訳文字列 msg = QObject.tr("Select a image file") print("msg : "+msg) if __name__ == "__main__": app = App() |
▼ 上手くいけばソフト文字列が翻訳される
引っかかるのはQTranslator.loadでの読み込み
1 |
translator.load(QLocale.system(), 'app', '.', path) |
各引数は次のような意味を持ってます。
- 第1引数はロケール
ここではシステム固有のロケール(QLocale.system())を使う。このロケールは日本語だったら ja__JP であることがほとんど(値は QLocale.system().name() から確認できる)
- 第2引数はqmファイルの名前
例えば app.ja_JP.qm だったら 'app' という値を指定する。ファイルパスは含める必要はないし、含めてはいけない。
- 第3引数は区切り文字
例えば app.ja_JP.qm だったら '.' という値を指定する。つまりqmファイルの名前と言語コード(ja_JP)を隔てる区切り文字を指定するってこと
- 第4引数はqmファイルの場所
実際にqmファイルがあるディレクトリパスを指定する。ただしディレクトリ区切り文字にはバックスラッシュ(\)ではなくスラッシュ(/)を使うこと。特にWindowsでは注意!
これだけ押さえておけば大丈夫
もし翻訳されないなら変換手順が間違ってます。
確実に手順を踏んでいけば翻訳も簡単
以上、PySideでのアプリ文字列翻訳でした。
色々ステップが多いから少し大変かもしれない。
でも確実に手順を踏んでいけば簡単です。ではまた