Quellcode für die Übersetzung schreiben
Schreiben Sie QML- und Qt C++-Quellcode so, dass Sie Anwendungen lokalisieren können:
- Markieren Sie Strings für die Übersetzung
- Verwenden Sie Parameter anstelle von verketteten Strings
- Behandlung von Pluralformen
- Regionale Zahleneinstellungen verwenden
- Internationalisierung von Datum, Uhrzeit und Währung
- Übersetzbare Daten als Textstrings markieren
- Kommentare für Übersetzer hinzufügen
- Identischen Text disambiguieren
- Tastaturkürzel übersetzbar machen
- Gebietsschema zur Erweiterung der Lokalisierungsfunktionen verwenden
- Aktivieren der Übersetzung
- Vorbereiten auf dynamische Sprachänderungen
Bei der Entwicklung von C++-Anwendungen, siehe auch Zusätzliche Überlegungen für C++-Code.
Zeichenketten für die Übersetzung markieren
Der meiste Text, der in einer Anwendung übersetzt werden muss, besteht entweder aus einzelnen Wörtern oder kurzen Sätzen. Diese erscheinen typischerweise als Fenstertitel, Menüpunkte, Tooltips und Beschriftungen von Schaltflächen, Kontrollkästchen und Optionsfeldern.
Qt minimiert die Leistungskosten für die Verwendung von Übersetzungen, indem es die Phrasen für jedes Fenster übersetzt, wenn es erstellt wird. In den meisten Anwendungen wird das Hauptfenster nur einmal erstellt. Dialoge werden oft einmal erstellt und dann nach Bedarf ein- und ausgeblendet. Sobald die erste Übersetzung stattgefunden hat, gibt es keinen weiteren Laufzeit-Overhead für die übersetzten Fenster. Nur die Fenster, die erstellt, zerstört und anschließend neu erstellt werden, verursachen Kosten für die Übersetzungsleistung.
Sie können Anwendungen erstellen, die zur Laufzeit die Sprache wechseln, aber das ist mit Aufwand und Kosten für die Laufzeitleistung verbunden.
Verwenden Sie Übersetzungsfunktionen, um für den Benutzer sichtbaren UI-Text für die Übersetzung in QML- und C++-Code zu markieren. Qt indiziert jede übersetzbare Zeichenkette anhand des Übersetzungskontextes, dem sie zugeordnet ist. Die gleiche Phrase kann in mehreren Kontexten vorkommen, ohne dass es zu Konflikten kommt. Wenn eine Phrase mehr als einmal in einem bestimmten Kontext vorkommt, wird sie nur einmal übersetzt und die Übersetzung wird auf jedes Vorkommen innerhalb des Kontexts angewendet.
QML: Verwendung von qsTr()
In QML können Sie die folgenden Funktionen verwenden, um für den Benutzer sichtbare Zeichenketten für die Übersetzung in .qml-Dateien zu markieren:
- qsTr()
- qsTranslate()
- qsTrId()
Normalerweise verwenden Sie die Funktion qsTr()
:
Text {
id: txt1
text: qsTr("Back")
}
Dieser Code macht Back zu einem Schlüsseleintrag in den Übersetzungsquelldateien (TS). Zur Laufzeit sucht das Übersetzungssystem nach dem Schlüsselwort Back und ruft dann den entsprechenden Übersetzungswert für das aktuelle Systemgebietsschema ab. Das Ergebnis wird an die Eigenschaft text
zurückgegeben, und die Benutzeroberfläche zeigt die entsprechende Übersetzung von Back für das aktuelle Gebietsschema an. Wenn keine Übersetzung gefunden wird, gibt qsTr()
die ursprüngliche Zeichenfolge zurück.
Der Übersetzungskontext kann für eine bestimmte Datei mit festgelegt werden:
pragma Translator: ChosenContext
oder
pragma Translator: "Chosen::Context"
Der über qsTranslate()
eingestellte Kontext hat Vorrang vor dem über pragma
Translator
eingestellten Kontext. In QML ist der Übersetzungskontext standardmäßig der Dateiname.
C++: Verwenden Sie tr()
In C++ verwenden Sie die Funktion tr(), um Text als übersetzbar zu markieren und übersetzten Text anzuzeigen. Der Übersetzungskontext ist der Name der QObject Unterklasse, in der der String verwendet wird. Um den Übersetzungskontext für neue QObject-basierte Klassen zu definieren, verwenden Sie das Makro Q_OBJECT in jeder neuen Klassendefinition.
Wenn tr()
aufgerufen wird, sucht es die übersetzbare Zeichenkette mit Hilfe eines QTranslator Objekts, das Sie auf dem Anwendungsobjekt installieren müssen, wie in Übersetzung aktivieren beschrieben.
Nehmen wir zum Beispiel an, dass LoginWidget
eine Unterklasse von QWidget ist:
Dies entspricht 99 % der für den Benutzer sichtbaren Zeichenketten, die Sie wahrscheinlich schreiben werden. Informationen zum Markieren von übersetzbaren String-Literalen finden Sie unter Markieren übersetzbarer Datentext-Strings.
Befindet sich der zitierte Text nicht in einer Memberfunktion einer QObject Unterklasse, verwenden Sie entweder die tr()
Funktion einer entsprechenden Klasse oder direkt die QCoreApplication::translate() Funktion:
void some_global_function(LoginWidget *logwid) { QLabel *label = new QLabel( LoginWidget::tr("Password:"), logwid); } void same_global_function(LoginWidget *logwid) { QLabel *label = new QLabel( QCoreApplication::translate("LoginWidget", "Password:"), logwid); }
Hinweis: Wenn Sie die automatische Konvertierung von const char *
nach QString deaktivieren, indem Sie Ihre Anwendung mit dem Makro QT_NO_CAST_FROM_ASCII
kompilieren, werden Sie höchstwahrscheinlich alle fehlenden Zeichenketten abfangen. Siehe QString::fromUtf8() und QString::fromLatin1() für weitere Informationen.
Verwenden Sie Parameter anstelle der Verkettung von Zeichenketten
Verschiedene Sprachen ordnen Wörter in Phrasen, Klauseln und Sätzen unterschiedlich an, daher sollten Sie keine Zeichenketten durch Verkettung von Wörtern und Daten erstellen. Verwenden Sie stattdessen %
, um Parameter in Zeichenketten einzufügen.
In der Zeichenkette After processing file %1, file %2 is next in line
zum Beispiel sind %1
und %2
nummerierte Parameter. Zur Laufzeit werden %1
und %2
durch den ersten bzw. zweiten Dateinamen ersetzt. Die gleichen nummerierten Parameter müssen in der Übersetzung erscheinen, aber nicht unbedingt in der gleichen Reihenfolge. Eine deutsche Übersetzung des Strings könnte die Phrasen umkehren. Zum Beispiel: Datei %2 wird bearbeitet, wenn Datei %1 fertig ist
. Beide nummerierten Parameter erscheinen in der Übersetzung, aber in umgekehrter Reihenfolge.
QML: Verwendung von .arg()
Das folgende QML-Snippet enthält eine Zeichenkette mit zwei numerischen Parametern %1
und %2
. Diese Parameter werden mit den Funktionen .arg()
eingefügt.
Text { text: qsTr("File %1 of %2").arg(counter).arg(total) }
%1
bezieht sich auf den ersten Parameter und %2
bezieht sich auf den zweiten Parameter, so dass dieser Code die folgende Ausgabe erzeugt: Datei 2 von 3.
C++: QString::arg() verwenden
In C++ verwenden Sie die Funktionen QString::arg(), um Parameter zu ersetzen:
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)); }
Dieser Code erzeugt eine Ausgabe wie: 5 von 10 Dateien kopiert. Kopieren: somefile.txt.
Behandlung von Pluralformen
Sie können einen zusätzlichen Integer-Parameter(n) an die Übersetzungsfunktionen übergeben und eine spezielle Notation für Pluralformen (%n
) in jeder übersetzbaren Zeichenkette verwenden.
Je nach dem Wert von n gibt die Übersetzungsfunktion eine andere Übersetzung mit der richtigen grammatikalischen Nummer für die Zielsprache zurück. Außerdem wird jedes Vorkommen von %n
durch den Wert von n ersetzt.
Die englische und die französische Übersetzung der Zeichenkette %n message(s) saved
erfordern zum Beispiel unterschiedliche Pluralformen.
n | Keine Übersetzung | Französisch | Englisch |
---|---|---|---|
0 | "0 Nachricht(en) gespeichert" | "0 gesicherte Nachricht(en)" | "0 gespeicherteNachrichten " |
1 | "1 Nachricht(en) gespeichert" | "1 Nachricht sauvegardé" | "1 Nachricht gespeichert" |
2 | "2 Nachricht(en) gespeichert" | "2Nachrichten sauvegardés" | "2 gespeicherteNachrichten " |
37 | "37 Nachricht(en) gespeichert" | "37Nachrichten sauvegardés" | "37 gespeicherteNachrichten " |
Dieses Idiom funktioniert auch mit Zielsprachen, die mehrere Pluralformen haben, wie z. B. eine Doppelform. Darüber hinaus behandelt das Idiom den Fall n == 0
korrekt für Sprachen wie Französisch, die den Singular verlangen.
Eine Zusammenfassung der Regeln, die Qt Linguist und lrelease
zur Übersetzung von Zeichenketten verwenden, die Pluralformen enthalten, finden Sie unter Übersetzungsregeln für Pluralformen.
Um Pluralformen in der Muttersprache zu behandeln, laden Sie auch eine TS-Datei für diese Sprache. Verwenden Sie die Kommandozeilenoption lupdate
-pluralonly
, um TS-Dateien zu erstellen, die nur Einträge mit Pluralformen enthalten.
Alternativ können Sie auch die Kommandozeilenoption -pluralonly
des Tools lconvert
verwenden, um alle Nicht-Pluralformen aus einer bestehenden TS-Datei zu entfernen.
QML-Beispiel
Der folgende QML-Codeausschnitt übersetzt den Quelltext in die korrekte Pluralform und ersetzt %n
durch den Wert von total
:
Text { text: qsTr("%n message(s) saved", "", total) }
C++-Beispiel
Der folgende C++-Codeausschnitt ersetzt %n
durch den Wert, den die Funktion count()
zurückgibt:
int n = messages.count(); showMessage(tr("%n message(s) saved", "", n));
Regionale Nummerneinstellungen verwenden
Wenn Sie bei der Angabe eines Parameters den Modifikator %L
einschließen, wird die Zahl entsprechend den aktuellen regionalen Einstellungen lokalisiert. Bei der Konvertierung wird das Standardgebietsschema verwendet, wenn Sie es festgelegt haben, oder andernfalls das systemweite Gebietsschema.
QML: %L verwenden
Im folgenden QML-Schnipsel beispielsweise formatiert %L1
den ersten Parameter gemäß den Zahlenformatierungskonventionen des aktuell ausgewählten Gebietsschemas (geografische Region):
Text { text: qsTr("%L1").arg(total) }
Wenn total
die Zahl 4321.56 ist, lautet die Ausgabe bei englischen Ländereinstellungen (Gebietsschema) 4.321.56, während sie bei deutschen Ländereinstellungen 4.321,56 lautet.
C++: %Ln verwenden
In C++ können Sie %Ln
verwenden, um eine lokalisierte Darstellung von n
zu erzeugen. Verwenden Sie QLocale::setDefault(), um das Standardgebietsschema festzulegen.
Internationalisierung von Datum, Uhrzeit und Währung
Stellen Sie Datum, Uhrzeit und Währung in den lokal bevorzugten Formaten dar.
QML: Verwenden Sie QtQml-Funktionen
QML verfügt nicht über spezielle In-String-Modifikatoren für die Formatierung von Datum und Uhrzeit. Stattdessen müssen Sie das aktuelle Gebietsschema (geografische Region) abfragen und die Methoden von Date verwenden, um den String zu formatieren.
Qt.locale()
gibt ein Locale Objekt zurück, das Informationen über das Gebietsschema enthält. Insbesondere die Eigenschaft Locale.name enthält die Sprache und das Land des aktuellen Gebietsschemas. Sie können den Wert so verwenden, wie er ist, oder ihn parsen, um den passenden Inhalt für das aktuelle Gebietsschema zu ermitteln.
Der folgende Ausschnitt ruft mit Date()
das aktuelle Datum und die Uhrzeit ab und konvertiert diese in eine Zeichenfolge für das aktuelle Gebietsschema. Anschließend wird die Datumszeichenfolge in den Parameter %1
für die entsprechende Übersetzung eingefügt.
Text { text: qsTr("Date %1").arg(Date().toLocaleString(Qt.locale())) }
Um Währungszahlen zu lokalisieren, verwenden Sie den Typ Number. Er verfügt über ähnliche Funktionen wie der Typ Date
zur Konvertierung von Zahlen in lokalisierte Währungsstrings.
C++: QLocale-Klasse verwenden
In C++ verwenden Sie QLocale::timeFormat() oder QLocale::toString(QTime) oder toString(QDate)
:
QLabel *label = new QLabel(this); label->setText(tr("Date %1").arg(QLocale().toString(QDate::currentDate()));
Markieren Sie übersetzbare Daten als Textstrings
Verwenden Sie _NoOp
Funktionen (in QML) und _NOOP
Makros (in C++), um übersetzbare String-Literale für die Extraktion durch das Tool lupdate
zu markieren.
QML: _NOOP-Funktionen verwenden
Verwenden Sie in QML die folgenden Funktionen, um übersetzbare String-Literale zu markieren:
Wenn der Benutzer die Systemsprache ohne Neustart ändert, werden die Strings in Arrays, Listenmodellen und anderen Datenstrukturen je nach System möglicherweise nicht automatisch aktualisiert. Um zu erzwingen, dass die Texte aktualisiert werden, wenn sie auf der Benutzeroberfläche angezeigt werden, müssen Sie die Strings mit der Funktion QT_TR_NOOP()
deklarieren. Wenn Sie dann die Objekte für die Anzeige auffüllen, müssen Sie die Übersetzung für jeden Text explizit abrufen.
Zum Beispiel:
ListModel { id: myListModel ListElement { //: Capital city of Finland name: QT_TR_NOOP("Helsinki") } } ... Text { text: qsTr(myListModel.get(0).name) // Get the translation of the name property in element 0 }
C++: _NOOP-Makros verwenden
Für übersetzbaren Text, der vollständig außerhalb einer Funktion liegt, verwenden Sie die Makros QT_TR_NOOP() und QT_TRANSLATE_NOOP(), die nur den Text ohne den Kontext ausgeben.
Ein Beispiel für 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]); }
Ein Beispiel für 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 QCoreApplication::translate("FriendlyConversation", greeting_strings[type]); }
Kommentare für Übersetzer hinzufügen
Sie können im Quelltext Kommentare vor einer als übersetzbar markierten Zeichenfolge einfügen, um deren Zweck zu verdeutlichen. Die Kommentare werden in die TS-Dateien aufgenommen, die Sie an den Übersetzer übergeben.
Hinweis: Die TS-Dateien sind XML-Dateien mit den Quelltexten und einem Platz für den übersetzten Text. Die aktualisierten TS-Dateien werden in binäre Übersetzungsdateien umgewandelt und als Teil der endgültigen Anwendung eingefügt.
QML: Verwendung von //: und //~
Im folgenden Codeschnipsel ist der Text in der Zeile //:
der Hauptkommentar für den Übersetzer.
Der Text in der Zeile //~
ist eine optionale Zusatzinformation. Das erste Wort des Textes wird als zusätzlicher Bezeichner im XML-Element in der TS-Datei verwendet, also stellen Sie sicher, dass das erste Wort nicht Teil des Satzes ist. Zum Beispiel wird der Kommentar Context Not related to back-stepping in der TS-Datei in <extra-Context>Not related to back-stepping
umgewandelt.
Text { id: txt1; // This UI string is only used here //: The back of the object, not the front //~ Context Not related to back-stepping text: qsTr("Back"); }
C++: Kommentarzeichen verwenden
Um Kommentare in C++ hinzuzufügen, kommentieren Sie die tr()
-Aufrufe in Ihrem Code mit Kommentaren der Form //:
oder indem Sie den Anfang und das Ende des Kommentars markieren.
In den folgenden Beispielen sind die Kommentare mit den Zeichenketten verknüpft, die im Kontext der einzelnen Aufrufe an tr()
übergeben werden:
//: This name refers to a host name. hostNameLabel->setText(tr("Name:")); /*: This text refers to a C++ code example. */ QString example = tr("Example");
Um optionale Kommentare hinzuzufügen, verwenden Sie:
//~ <field name> <field contents>
Der Feldname sollte aus einem Domänenpräfix (möglicherweise die konventionelle Dateierweiterung des Dateiformats, an das sich das Feld anlehnt), einem Bindestrich und dem eigentlichen Feldnamen in durch Unterstriche getrennter Schreibweise bestehen. Für die Speicherung in TS-Dateien wird der Feldname zusammen mit dem Präfix extra-
einen XML-Elementnamen bilden. Der Feldinhalt wird mit XML-Escapern versehen, erscheint aber ansonsten wortwörtlich als Inhalt des Elements. Sie können jeder Nachricht eine beliebige Anzahl von eindeutigen Feldern hinzufügen.
Beispiel:
//: This is a comment for the translator. //= qtn_foo_bar //~ loc-layout_id foo_dialog //~ loc-blank False //~ magic-stuff This might mean something magic. QString text = MyMagicClass::tr("Sim sala bim.");
In C++ verwenden Sie ein Gleichheitszeichen, um einen eindeutigen Bezeichner hinzuzufügen:
//= <id>
Sie können das Schlüsselwort TRANSLATOR für Übersetzerkommentare verwenden. Metadaten, die direkt vor dem Schlüsselwort TRANSLATOR erscheinen, gelten für die gesamte TS-Datei.
Identischen Text disambiguieren
Das Übersetzungssystem fasst die UI-Textstrings zu eindeutigen Elementen zusammen, um zu vermeiden, dass derselbe Text mehrfach übersetzt werden muss. Ein Text kann jedoch identisch mit einem anderen Text aussehen, aber eine andere Bedeutung haben. Im Englischen bedeutet back zum Beispiel sowohl einen Schritt zurück als auch den Teil eines Objekts, der der Vorderseite gegenüberliegt. Sie müssen dem Übersetzungssystem diese beiden unterschiedlichen Bedeutungen mitteilen, damit der Übersetzer zwei separate Übersetzungen erstellen kann.
QML: Hinzufügen eines Disambiguators zu qsTr()
Fügen Sie in QML eine disambiguierende Zeichenfolge als zweiten Parameter der Funktion qsTr()
hinzu.
Im folgenden Codeschnipsel unterscheidet die ID not front
diesen Back-Text von dem zurückgehenden Back-Text:
Text { id: txt1 // This UI string is used only here //: The back of the object, not the front //~ Context Not related to back-stepping text: qsTr("Back", "not front") }
C++: Hinzufügen eines Disambiguators zu tr()
Übergeben Sie in C++ eine disambiguierende Zeichenkette im Aufruf von tr().
Im folgenden Codeschnipsel unterscheidet die ID recipient
den Namen des Empfängers von dem des Absenders:
MyWindow::MyWindow() { QLabel *senderLabel = new QLabel(tr("Name:")); QLabel *recipientLabel = new QLabel(tr("Name:", "recipient")); ...
Tastaturkürzel übersetzbar machen
In seiner häufigsten Form beschreibt ein Tastaturkürzel eine Tastenkombination, die Sie drücken, um eine bestimmte Aktion auszuführen. Verwenden Sie für standard shortcuts eine Standardtaste, um die plattformspezifische Tastenfolge abzufragen, die mit jeder Tastenkombination verbunden ist.
Für benutzerdefinierte Tastenkombinationen verwenden Sie menschenlesbare Zeichenfolgen, wie z. B. Strg+Q oder Alt+F. Sie können sie in die entsprechenden Tastenkombinationen für die Sprecher verschiedener Sprachen übersetzen.
Wenn Sie Tastaturkürzel in Ihrer Anwendung fest kodieren, können Übersetzer sie nicht überschreiben.
Wenn Sie Tastenkombinationen in Menüelementen und Schaltflächentexten verwenden, zeigt ein mnemonisches Zeichen (durch Unterstreichung gekennzeichnet) an, dass das Drücken der Alt- oder Strg-Taste mit dem unterstrichenen Zeichen die gleiche Aktion ausführt wie das Klicken auf das Menüelement oder das Drücken der Schaltfläche.
Anwendungen verwenden beispielsweise häufig F als mnemonisches Zeichen im Menü File, so dass Sie entweder auf den Menüpunkt klicken oder Alt+F drücken können, um das Menü zu öffnen. Um das mnemonische Zeichen in der übersetzbaren Zeichenfolge ("Datei") zu definieren, stellen Sie ihm ein kaufmännisches Und voran: "&File"
. Die Übersetzung der Zeichenfolge sollte ebenfalls ein kaufmännisches Und enthalten, vorzugsweise vor demselben Zeichen.
QML-Beispiel
In QML:
Menu { id: fileMenu title: qsTr("&File") MenuItem { objectName: "quitMenuItem" text: qsTr("E&xit") onTriggered: Qt.quit() } }
C++: Verwenden Sie die Klasse QKeySequence
In C++ verwenden Sie die Objekte QAction und QKeySequence, um die Tastenkombinationen anzugeben, die Aktionen auslösen:
exitAct = new QAction(tr("E&xit"), this); exitAct->setShortcuts(QKeySequence::Quit);
Die Übersetzungen der Tastenkombinationen sind mit dem Kontext QShortcut verbunden.
Verwenden Sie Locale, um die Lokalisierungsfunktionen zu erweitern
Es kann sein, dass sich unterschiedliche Grafiken oder Audiodateien für verschiedene geografische Regionen besser eignen.
Versuchen Sie generell, die Lokalisierung von Bildern zu vermeiden. Erstellen Sie Symbole, die weltweit geeignet sind, und verlassen Sie sich nicht auf lokale Wortspiele oder überspannte Metaphern. Es kann jedoch sein, dass Sie die Bilder der nach links und rechts zeigenden Pfeile für arabische und hebräische Sprachumgebungen umkehren müssen.
Das Gebietsschema ist einer der Standard-Datenselektoren, so dass Sie die Dateiauswahl verwenden können, um verschiedene Bilder anzuzeigen, die Sie je nach dem Gebietsschema des Systems als Ressourcen bereitstellen.
Die QML- und C++-Codebeispiele in den folgenden Abschnitten gehen davon aus, dass Sie die folgenden Dateien in den Anwendungsressourcen bereitstellen und Sprach- und Ländercodes als Unterordnernamen verwenden:
images ├── language-icon.png ├── +en_GB │ └── language-icon.png └── +fi_FI └── language-icon.png
QML: Bildquelle festlegen
Der folgende QML-Codeausschnitt zeigt, wie man ein Bild als Symbolquelle entsprechend dem aktuellen Gebietsschema auswählt:
icon.source: "qrc:/images/language-icon.png"
C++: QFileSelector verwenden
Der folgende C++-Codeausschnitt verwendet QFileSelector, um ein Sprachsymbol aus dem Ordner images
entsprechend dem Systemgebietsschema auszuwählen:
const QFileSelector selector; const QIcon languageIcon(selector.select(":/images/language-icon.png"));
Enable Translation
TS-Dateinamen müssen ISO-Sprach- und Ländercodes enthalten:
- Sprache ist ein ISO-639-Sprachcode in Kleinbuchstaben.
- Land ist ein zweistelliger ISO-3166-Ländercode in Großbuchstaben.
Beispiel: qml_de.ts
setzt die Zielsprache auf Deutsch, und qml_de_CH.ts
setzt die Zielsprache auf Deutsch und das Zielland auf die Schweiz. Das Tool lrelease
erzeugt QM-Dateien mit den Namen qml_de.qm
und qml_de_CH.qm
, die von der Anwendung abhängig vom Systemgebietsschema geladen werden.
QML: QQmlApplicationEngine verwenden
In QML verwenden Sie QQmlApplicationEngine, um automatisch Übersetzungsdateien aus einem Unterverzeichnis namens i18n
in das Verzeichnis zu laden, das die QML-Hauptdatei enthält. Die Namen der Übersetzungsdateien müssen das Präfix qml_
haben. Zum Beispiel: qml_en_US.qm
.
Anwendungen laden die Übersetzungen neu, wenn sich der Wert der Eigenschaft QJSEngine::uiLanguage oder Qt.uiLanguage ändert.
C++: QTranslator verwenden
In C++ müssen die TS-Dateinamen den Namen der Anwendung enthalten. Zum Beispiel: app_de_DE.ts
.
Normalerweise sieht die Funktion main()
Ihrer Qt C++ Anwendung so aus:
int main(int argc, char *argv[]) { QApplication app(argc, argv); QTranslator myappTranslator; if (myappTranslator.load(QLocale::system(), u"myapp"_s, u"_"_s, u":/i18n"_s)) app.installTranslator(&myappTranslator); return app.exec(); }
Für eine übersetzungsfähige Anwendung erstellen Sie ein QTranslator -Objekt, load eine Übersetzung entsprechend dem UI-Anzeigegebietsschema des Benutzers zur Laufzeit und installieren das Übersetzerobjekt in die Anwendung.
Vorbereiten auf dynamische Sprachänderungen
Sowohl Qt Widgets als auch Qt Quick verwenden das Ereignissystem von Qt, um Klassen über Übersetzungsänderungen zu informieren.
LanguageChange Ereignisse werden gepostet, wenn Sie die Funktion QCoreApplication::installTranslator() verwenden, um eine neue Übersetzung zu installieren. Andere Anwendungskomponenten können auch Widgets oder QML-Typen, die vom Typ Item abgeleitet sind, dazu zwingen, sich selbst zu aktualisieren, indem sie LanguageChange
Ereignisse an sie senden.
Standardmäßig werden LanguageChange
Ereignisse an alle Top-Level-Fenster weitergegeben, und von dort werden sie durch den gesamten Baum von Widgets oder QML-Typen, die von Item abgeleitet sind, weitergegeben.
Qt Widgets: Überschreiben von changeEvent
Der Standard-Ereignishandler für QWidget Unterklassen reagiert auf das QEvent::LanguageChange Ereignis und ruft bei Bedarf die changeEvent()
Funktion auf.
Um Qt Widgets auf Änderungen an den installierten QTranslator Objekten aufmerksam zu machen, reimplementieren Sie die Funktion changeEvent() des Widgets, um zu prüfen, ob das Ereignis ein LanguageChange Ereignis ist und aktualisieren Sie den von Widgets angezeigten Text mit der Funktion tr(). Ein Beispiel:
void MyWidget::changeEvent(QEvent *event) { if (event->type() == QEvent::LanguageChange) { titleLabel->setText(tr("Document Title")); ... okPushButton->setText(tr("&OK")); } else QWidget::changeEvent(event); }
Wenn Sie Qt Widgets Designer UI-Dateien (.ui) und uic
verwenden, können Sie die neuen Übersetzungsdateien lesen und ui.retranslateUi(this)
direkt aufrufen:
void MyWidget::changeEvent(QEvent *event) { if (event->type() == QEvent::LanguageChange) { ui.retranslateUi(this); } else QWidget::changeEvent(event); }
Um andere Änderungsereignisse weiterzugeben, rufen Sie die Standardimplementierung der Funktion auf.
Die Liste der installierten Übersetzer könnte sich als Reaktion auf ein LocaleChange -Ereignis ändern, oder die Anwendung könnte eine Benutzeroberfläche bereitstellen, die es dem Benutzer ermöglicht, die aktuelle Anwendungssprache zu ändern.
QML: Überschreibungsereignis für von Item abgeleitete Typen
Für einfache QML-Anwendungen ohne benutzerdefinierte, in C++ registrierte Typen genügt die Verwendung von QQmlApplicationEngine, um eine Aktualisierung aller Übersetzungsbindungen auszulösen.
Wenn Sie jedoch einen von QQuickItem abgeleiteten Typ registriert haben und eine seiner Eigenschaften übersetzten Text enthält (oder anderweitig sprachabhängig ist), überschreiben Sie dessen event method und geben Sie das Änderungssignal der Eigenschaft darin aus (oder rufen Sie notify im Falle von bindbaren Eigenschaften auf). Zum Beispiel:
class MyItem : public QQuickItem { Q_OJBECT QML_ELEMENT Q_PROPERTY(QString greeting READ greeting NOTIFY greetingChanged) public signals: void greetingChanged(); public: QString greeting() const { return tr("Hello World!"); } bool event(QEvent *ev) override { if (ev->type() == QEvent::LanguageChange) emit greetingChanged(); return QQuickItem::event(ev); } };
Dies stellt sicher, dass jede Bindung in QML, in der die Eigenschaft verwendet wird, neu ausgewertet wird und die Sprachänderung berücksichtigt.
Generische QObject-abgeleitete Klassen: Event-Filter verwenden
Es gibt Klassen, die weder von QWidget noch von QQuickItem abgeleitet sind, die aber dennoch mit Sprachänderungsereignissen umgehen müssen. In diesem Fall sollten Sie einen Ereignisfilter auf QCoreApplication installieren.
class CustomObject : public QObject { Q_OBJECT public: QList<QQuickItem *> managedItems; CustomObject(QOject *parent = nullptr) : QObject(parent) { QCoreApplication::instance()->installEventFilter(this); } bool eventFilter(QObject *obj, QEvent *ev) override { if (obj == QCoreApplication::instance() && ev->type() == QEvent::LanguageChange) { for (auto item : std::as_const(managedItems)) QCoreApplication::sendEvent(item, ev); // do any further work on reaction, e.g. emit changed signals } return false; } };
Dies kann notwendig sein, wenn die Klasse übersetzte Zeichenketten bereitstellt, die später in einer Benutzeroberfläche angezeigt werden (z. B. eine benutzerdefinierte item model), oder wenn die Klasse als Container für Widgets oder Quick Items fungiert und daher für die Weiterleitung des Ereignisses an diese verantwortlich ist.
Zusätzliche Überlegungen für C++-Code
Die folgenden Abschnitte enthalten weitere Informationen über die Verwendung der Qt C++ Klassen und Funktionen in übersetzbaren Anwendungen:
- QString für den gesamten für den Benutzer sichtbaren Text verwenden
- Definieren Sie einen Übersetzungskontext
- Nicht-Qt-Klassen übersetzen
- Übersetzen von Text, der außerhalb einer QObject-Unterklasse liegt
QString für den gesamten für den Benutzer sichtbaren Text verwenden
QString verwendet intern die Unicode-Kodierung, so dass Sie vertraute Textverarbeitungsoperationen verwenden können, um alle Sprachen der Welt transparent zu verarbeiten. Da alle Qt-Funktionen, die Text für den Benutzer darstellen, ein QString -Objekt als Parameter verwenden, gibt es auch keinen Overhead bei der Konvertierung von char *
nach QString.
Definieren eines Übersetzungskontextes
Der Übersetzungskontext für QObject und jede QObject Unterklasse ist der Klassenname selbst. Wenn Sie die Subklasse QObject untergliedern, verwenden Sie das Makro Q_OBJECT in der Klassendefinition, um den Übersetzungskontext außer Kraft zu setzen. Das Makro setzt den Kontext auf den Namen der Unterklasse.
Die folgende Klassendefinition enthält zum Beispiel das Makro Q_OBJECT, das eine neue Funktion tr()
implementiert, die den Kontext MainWindow
verwendet:
class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(); ...
Wenn Sie Q_OBJECT nicht in einer Klassendefinition verwenden, wird der Kontext von der Basisklasse geerbt. Da beispielsweise alle QObject-basierten Klassen in Qt einen Kontext bereitstellen, verwendet eine neue QWidget -Unterklasse, die ohne Q_OBJECT -Makro definiert ist, den QWidget
-Kontext, wenn Sie ihre tr()
-Funktion aufrufen.
Übersetzen von Nicht-Qt-Klassen
Sie müssen zusätzliche Informationen für lupdate
über Strings in Klassen bereitstellen, die nicht QObject erben oder das Q_OBJECT Makro verwenden. Um einer Nicht-Qt-Klasse Übersetzungsunterstützung hinzuzufügen, können Sie das Makro Q_DECLARE_TR_FUNCTIONS() verwenden. Ein Beispiel:
class MyClass { Q_DECLARE_TR_FUNCTIONS(MyClass) public: MyClass(); ... };
Dadurch wird die Klasse mit tr()-Funktionen ausgestattet, die Sie verwenden können, um mit der Klasse verknüpfte Zeichenketten zu übersetzen, und lupdate
ermöglicht es, übersetzbare Zeichenketten im Quellcode zu finden.
Alternativ dazu können Sie die Funktion QCoreApplication::translate() mit einem bestimmten Kontext aufrufen, den lupdate
und Qt Linguist erkennen.
Übersetzen von Text, der sich außerhalb einer QObject-Unterklasse befindet
Wenn sich der zitierte Text nicht in einer Memberfunktion einer QObject Unterklasse befindet, verwenden Sie entweder die Funktion tr()
einer entsprechenden Klasse oder direkt die Funktion 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( QCoreApplication::translate("LoginWidget", "Password:"), logwid); }
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.