In Qt ist es relativ einfach eine Anwendung zu übersetzen. Unterstützt wird man dabei vom Qt-Linguist.
Um ein Programm in mehreren Sprachen verfügbar zu machen, müssen alle zu übersetzenden Strings an die Methode QObject::tr()
übergeben werden. Diese gibt den String in der ausgewählten Sprache zurück. Beispiel:
QPushButton *button = new QPushButton( QObject::tr( "Quit" );
Befindet man sich innerhalb des QObject
-Namespaces (in allen von QObject
und damit auch QWidget
abgeleiteten Klassen der Fall), kann das QObject::
weggelassen werden:
QPushButton *button = new QPushButton( tr( "Quit" ) ) );
Bei dynamischen Strings sollte unbedingt QString::arg()
anstatt des +-Operators verwendet werden, da sich der Satzbau in den Sprachen unterscheidet. Also nicht:
label->setText( tr( QString::number( numTries ) + " tries remaining!" ) );
sondern:
label->setText( tr( "%1 tries remaining!" ).arg( numTries ) );
Zuerst muss der Pfad und die Namen der Übersetzungsdateien manuell am Ende der Projektdatei (*.pro) eingetragen werden. Als Beispiel nennen wir unser Programm proggen
:
// proggen.pro TRANSLATIONS = lang/files/proggen_en.ts \ lang/files/proggen_de.ts
Nun werden über das Programm lupdate
die Übersetzungsdateien erstellt. Dabei muss das Programm mit der Projektdatei als Parameter aufgerufen werden:
lupdate proggen.pro
Jetzt haben wir die in der Projektdatei genannten *.ts-Dateien. Das sind lediglich XML-Dateien, die auch mit einem normalen Texteditor geöffnet werden können. Wesentlich einfacher ist es aber sie mit dem Qt-Linguist zu öffnen und zu bearbeiten.
bearbeiten
Sind wir damit fertig, können wir lrelease
auf das Projekt ausführen.
lrelease proggen.pro
Damit haben wir optimierte *.qm-Dateien, die wir im Programm verwenden können.
Um die Übersetzungsdateien im Programm zu verwenden, müssen sie über die Klasse QTranslator
geladen und installiert werden. Dies muss geschehen bevor sichtbarer Text über tr()
abgefragt wird. Eine Integration über dein Resource Compiler ist ebenfalls möglich und auch sehr praktisch.
QApplication app( argc, argv ); QTranslator translator; translator.load( ":/proggen_de" ); app.installTranslator( &translator );
Danach gibt tr()
den jeweiligen Text aus der Übersetzungsdatei zurück.
Eine Änderung der Sprache während das Programm läuft ist etwas komplizierter. Wie bereits erwähnt, verändert das QTranslator
-Objekt den von tr()
zurückgegebenen Text. Dieser Text wird aber normalerweise nur ein einziges Mal abgefragt. Ändern wir im laufenden Programm die Sprache, gibt zwar tr()
den richtigen Text zurück, jedoch werden Widgets (bzw. Variablen allgemein) nicht automatisch aktualisiert.
Um dieses Problem zu umgehen, können wir einen Event-Handler festlegen, der bei Änderung der Sprache aufgerufen wird. In diesem muss dann der Text der Widgets neu abgefragt und übernommen werden.
void MyWidget::changeEvent( QEvent *event ) { if( event->type() == QEvent::LanguageChange ) updateWidgetLanguage(); else QWidget::changeEvent( event ); } void MyWidget::updateWidgetLanguage() { // ... }