Quellcode für die Übersetzung schreiben
Schreiben Sie QML- und Qt-C++-Quellcode so, dass Sie Anwendungen lokalisieren können:
- Markieren Sie Zeichenfolgen für die Übersetzung
- Verwenden Sie Parameter anstelle von Zeichenfolgenverkettungen
- Behandeln Sie Pluralformen
- Verwenden Sie regionale Zahleneinstellungen
- Internationalisieren Sie Datum, Uhrzeit und Währung
- Markieren Sie übersetzbare Textzeichenfolgen
- Fügen Sie Kommentare für Übersetzer hinzu
- Identische Textstellen eindeutig zuordnen
- Tastaturkürzel übersetzbar machen
- Lokalisierungsfunktionen mithilfe von Locale erweitern
- Übersetzung aktivieren
- Vorbereitung auf dynamische Sprachwechsel
Beachten Sie bei der Entwicklung von C++-Anwendungen auch die zusätzlichen Überlegungen zum C++-Code.
Zeichenfolgen zur Übersetzung markieren
Der Großteil des Textes, der in einer Anwendung übersetzt werden muss, besteht entweder aus einzelnen Wörtern oder kurzen Phrasen. Diese erscheinen typischerweise als Fenstertitel, Menüeinträge, Tooltips sowie Beschriftungen für Schaltflächen, Kontrollkästchen und Optionsfelder.
Qt minimiert den Leistungsaufwand für die Verwendung von Übersetzungen, indem die Phrasen für jedes Fenster bei dessen Erstellung übersetzt werden. In den meisten Anwendungen wird das Hauptfenster nur einmal erstellt. Dialogfelder werden oft einmal erstellt und dann je nach Bedarf ein- und ausgeblendet. Sobald die anfängliche Übersetzung erfolgt ist, entsteht kein weiterer Laufzeit-Overhead für die übersetzten Fenster. Lediglich bei Fenstern, die erstellt, zerstört und anschließend erneut erstellt werden, entstehen Leistungsbeeinträchtigungen durch die Übersetzung.
Sie können Anwendungen erstellen, die zur Laufzeit die Sprache wechseln, doch dies ist mit Aufwand verbunden und geht mit einem Leistungsaufwand zur Laufzeit einher.
Verwenden Sie Übersetzungsfunktionen, um für den Benutzer sichtbaren UI-Text im Qt Qml- und C++-Code zur Übersetzung zu markieren. Qt unterstützt zwei Ansätze zur Identifizierung übersetzbarer Texte: den textbasierten und den ID-basierten.
Beim textbasierten Übersetzungsansatz indiziert Qt jede übersetzbare Zeichenfolge anhand des Übersetzungskontexts und optional anhand eines ihr zugeordneten, zur Eindeutigkeit dienenden Kommentars. Dieselbe Phrase kann in mehr als einem Kontext vorkommen, ohne dass es zu Konflikten kommt. Wenn eine Phrase in einem bestimmten Kontext mehr als einmal vorkommt, wird sie nur einmal übersetzt, und die Übersetzung wird auf jedes Vorkommen innerhalb des Kontexts angewendet.
Beim ID-basierten Übersetzungsansatz wird jede Übersetzung durch eine eindeutige ID identifiziert. Die IDs sind projektweit eindeutig. Wenn eine ID in einem Projekt mehrmals vorkommt, wird sie nur einmal übersetzt, und die Übersetzung wird auf jedes Vorkommen innerhalb des Projekts angewendet.
QML
In QML können Sie die folgenden Funktionen verwenden, um für den Benutzer sichtbare Zeichenfolgen in .qml-Dateien zur Übersetzung zu kennzeichnen:
- qsTr(): Textbasierte Übersetzung
- qsTranslate(): Textbasierte Übersetzung
- qsTrId(): ID-basierte Übersetzung
Textbasierte qsTr():
Text {
id: txt1
text: qsTr("Back")
}Dieser Code macht „Back“ zu einem Schlüssel-Eintrag in den Übersetzungsquelldateien (TS). Zur Laufzeit sucht das Übersetzungssystem im aktuellen Kontext (siehe unten) nach dem Schlüsselwort „Back“ und ruft dann den entsprechenden Übersetzungswert für die aktuelle Systemlokalisierung ab. Das Ergebnis wird an die Eigenschaft „ text “ zurückgegeben, und die Benutzeroberfläche zeigt die passende Übersetzung von „Back“ für die aktuelle Lokalisierung an. Wird keine Übersetzung gefunden, gibt „ qsTr() “ die ursprüngliche Zeichenfolge zurück.
Der Übersetzungskontext kann für eine bestimmte Datei wie folgt festgelegt werden:
pragma Translator: ChosenContextoder
pragma Translator: "Chosen::Context"Der über ` qsTranslate() ` festgelegte Kontext hat Vorrang vor dem über ` pragma ` festgelegten Kontext Translator. In QML ist der Übersetzungskontext standardmäßig der Dateiname.
ID-basiertes `qsTrId()`:
Text {
id: txt1
//% "Back"
text: qsTrId("BackID")
}Dieser Code macht „BackID“ zu einem eindeutigen Schlüsseleintrag in den Übersetzungsquelldateien (TS) und schreibt „Back“ als Quelltext. Zur Laufzeit sucht das Übersetzungssystem nach der ID „BackID“ und ruft dann den entsprechenden Übersetzungswert (oder, falls nicht übersetzt, den Quelltext) für die aktuelle Systemlokalisierung ab. Das Ergebnis wird an die Eigenschaft „ text “ zurückgegeben, und die Benutzeroberfläche zeigt die entsprechende Übersetzung von „BackID“ für die aktuelle Ländereinstellung an. Wird in den TS-Dateien kein Eintrag mit der ID „BackID“ gefunden, gibt „ qsTrId() “ die ID selbst zurück. Dies sollte unter normalen Umständen nicht vorkommen.
C++
In C++ können Sie die folgenden Funktionen verwenden, um für den Benutzer sichtbare Zeichenfolgen zur Übersetzung zu kennzeichnen:
- tr(): Textbasierte Übersetzung
- QCoreApplication::translate(): Textbasierte Übersetzung
- QTranslator::translate(): Textbasierte Übersetzung
- qtTrId(): ID-basierte Übersetzung
- Weitere Optionen finden Sie unter linguist-id-based-i18n.html
Textbasierte tr()
Verwenden Sie die Funktion ` tr()` (tr()), um Text als übersetzbar zu kennzeichnen und übersetzten Text anzuzeigen. Der Übersetzungskontext ist der Name der Unterklasse von ` QObject `, in der die Zeichenkette verwendet wird. Um den Übersetzungskontext für neue, auf ` QObject` basierende Klassen zu definieren, verwenden Sie das Makro ` Q_OBJECT ` in jeder neuen Klassendefinition.
Wenn „ tr() “ aufgerufen wird, sucht die Funktion die übersetzbare Zeichenfolge mithilfe eines „ QTranslator “-Objekts, das Sie, wie unter „Übersetzung aktivieren“ beschrieben, am Anwendungsobjekt anlegen müssen.
Angenommen, „ LoginWidget “ ist eine Unterklasse von „ QWidget “:
Dies deckt 99 % der für den Benutzer sichtbaren Zeichenfolgen ab, die Sie wahrscheinlich schreiben werden. Informationen zum Markieren von Zeichenfolgenliteralen als übersetzbar finden Sie unter „Übersetzbare Datenzeichenfolgen markieren“.
Befindet sich der in Anführungszeichen gesetzte Text nicht in einer Member-Funktion einer Unterklasse von ` QObject `, verwenden Sie entweder die Funktion ` tr() ` einer geeigneten 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);
}ID-basiertes `qtTrId()`
qtTrId() gibt eine durch eine ID identifizierte übersetzte Zeichenkette zurück. Anstatt also die übersetzbare Zeichenkette selbst in die Funktion zu schreiben, geben Sie die ID der Übersetzung an. Der Quelltext (Standardzeichenfolge) wird in Metastring-Notation geschrieben: //%. Wenn der Text nicht übersetzt ist, wird der durch ` //% ` annotierte Quelltext zurückgegeben. Wird keine passende ID gefunden, wird die ID selbst zurückgegeben. Dies sollte unter normalen Umständen nicht vorkommen.
Dieser Code macht „PasswordID“ zu einem eindeutigen Schlüsseleintrag in den Übersetzungsquelldateien (TS) und schreibt „Password:“ als Quelltext. Zur Laufzeit sucht das Übersetzungssystem nach der ID „PasswordID“ und ruft dann den entsprechenden Übersetzungswert (oder, falls nicht übersetzt, den Quelltext) für die aktuelle System-Locale ab.
Hinweis: Wenn Sie die automatische Konvertierung von „ const char * “ in „ QString “ deaktivieren, indem Sie Ihre Anwendung mit dem definierten Makro „ QT_NO_CAST_FROM_ASCII “ kompilieren, werden Sie höchstwahrscheinlich alle fehlenden Zeichenfolgen erkennen. Weitere Informationen finden Sie unter QString::fromUtf8() und QString::fromLatin1().
Verwenden Sie Parameter anstelle von Zeichenfolgenverkettungen
Verschiedene Sprachen ordnen Wörter in Phrasen, Satzteilen und Sätzen unterschiedlich an. Erstellen Sie daher keine Zeichenfolgen durch die Verkettung von Wörtern und Daten. Verwenden Sie stattdessen %, um Parameter in Zeichenfolgen einzufügen.
Beispielsweise sind in der Zeichenkette After processing file %1, file %2 is next in line die Elemente „ %1 “ und „ %2 “ nummerierte Parameter. Zur Laufzeit werden „ %1 “ und „ %2 “ durch den ersten bzw. den zweiten Dateinamen ersetzt. Die gleichen nummerierten Parameter müssen in der Übersetzung vorkommen, jedoch nicht unbedingt in derselben Reihenfolge. Eine deutsche Übersetzung der Zeichenfolge könnte die Reihenfolge der Ausdrücke umkehren. Zum Beispiel: Datei %2 wird bearbeitet, wenn Datei %1 fertig ist. Beide nummerierten Parameter erscheinen in der Übersetzung, jedoch in umgekehrter Reihenfolge.
QML: Verwenden Sie .arg()
Der folgende QML-Ausschnitt enthält eine Zeichenkette mit zwei nummerierten 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 auf den zweiten Parameter, sodass dieser Code eine Ausgabe wie „Datei 2 von 3“ erzeugt.
Vermeiden Sie die Verwendung von Template-Zeichenketten mit Argumenten, da die resultierende Zeichenkette zur Laufzeit und nicht zur Kompilierungszeit definiert wird. Infolgedessen können die Übersetzungstools keine korrekte Übersetzung für die Template-Zeichenketten finden.
C++: Verwenden Sie QString::arg()
Verwenden Sie in C++ die Funktionen ` QString::arg()` zum Ersetzen von Parametern:
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 den Übersetzungsfunktionen einen zusätzlichen ganzzahligen Parameter (n) übergeben und in jeder übersetzbaren Zeichenkette eine spezielle Notation für Pluralformen (%n) verwenden.
Je nach Wert von n gibt die Übersetzungsfunktion eine andere Übersetzung zurück, mit der grammatikalisch korrekten Zahl in der Zielsprache. Außerdem wird jedes Vorkommen von „ %n “ durch den Wert von n ersetzt.
Beispielsweise erfordern die englischen und französischen Übersetzungen der Zeichenfolge „ %n message(s) saved “ unterschiedliche Pluralformen.
| n | Keine Übersetzung | Französisch | Englisch |
|---|---|---|---|
| 0 | „0 Nachricht(en) gespeichert“ | „0 Nachricht(en) gespeichert“ | „0 gespeicherteNachrichten “ |
| 1 | „1 Nachricht(en) gespeichert“ | „1 Nachricht gespeichert“ | „1 Nachricht gespeichert“ |
| 2 | „2 Nachrichten gespeichert“ | „2Nachrichten gespeichert“ | „2Nachrichten gespeichert“ |
| 37 | „37 Nachrichten gespeichert“ | „37Nachrichten gespeichert“ | „37Nachrichten gespeichert“ |
Diese Redewendung funktioniert auch bei Zielsprachen, die mehrere Pluralformen haben, wie beispielsweise eine Dualform. Darüber hinaus behandelt die Redewendung den Fall „n == 0 “ korrekt für Sprachen wie Französisch, die den Singular erfordern.
Eine Zusammenfassung der Regeln, nach denen „ Qt Linguist “ und „ lrelease “ Zeichenfolgen mit Pluralformen übersetzen, finden Sie unter „Übersetzungsregeln für Pluralformen“.
Um Pluralformen in der Zielsprache zu verarbeiten, laden Sie ebenfalls eine TS-Datei für diese Sprache. Verwenden Sie die Befehlszeilenoption „ -pluralonly “ des Tools „ lupdate “, um TS-Dateien zu erstellen, die ausschließlich Einträge mit Pluralformen enthalten.
Alternativ können Sie die Befehlszeilenoption „ -pluralonly “ des Tools „ lconvert “ verwenden, um alle Nicht-Pluralformen aus einer vorhandenen 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 Zahleneinstellungen verwenden
Wenn Sie bei der Angabe eines Parameters den Modifikator „ %L “ einfügen, wird die Zahl entsprechend den aktuellen regionalen Einstellungen lokalisiert. Die Konvertierung verwendet die Standard-Locale, sofern Sie diese festgelegt haben, andernfalls die systemweite Locale.
QML: Verwenden Sie %L
Im folgenden QML-Ausschnitt formatiert beispielsweise „ %L1 “ den ersten Parameter gemäß den Zahlenformatierungskonventionen der aktuell ausgewählten Locale (geografische Region):
Text {
text: qsTr("%L1").arg(total)
}Wenn „ total “ die Zahl 4321,56 ist, lautet die Ausgabe bei englischen Ländereinstellungen (Locale) 4.321,56, bei deutschen Ländereinstellungen hingegen 4.321,56.
C++: Verwenden Sie %Ln
In C++ können Sie ` %Ln ` verwenden, um eine lokalisierte Darstellung von ` n` zu erzeugen. Verwenden Sie ` QLocale::setDefault()` zum Festlegen der Standard-Locale.
Datum, Uhrzeit und Währung internationalisieren
Stellen Sie Datum, Uhrzeit und Währung in den lokal bevorzugten Formaten dar.
QML: Verwenden Sie QtQml-Funktionen
QML verfügt über keine speziellen Modifikatoren innerhalb von Zeichenketten zur Formatierung von Datums- und Zeitangaben. Stattdessen müssen Sie die aktuelle Locale (geografische Region) abfragen und die Methoden von `Date` verwenden, um die Zeichenkette zu formatieren.
Qt.locale() gibt ein ` Locale `-Objekt zurück, das Informationen zur Locale enthält. Insbesondere enthält die Eigenschaft ` Locale.name ` die Sprache und das Land der aktuellen Locale. Sie können den Wert unverändert verwenden oder ihn analysieren, um den passenden Inhalt für die aktuelle Locale zu ermitteln.
Der folgende Codeausschnitt ruft mit ` Date()` das aktuelle Datum und die aktuelle Uhrzeit ab und wandelt diese dann in eine Zeichenfolge für die aktuelle Locale um. Anschließend wird die Datumszeichenfolge in den Parameter ` %1 ` eingefügt, um die entsprechende Übersetzung zu erhalten.
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 Umwandlung von Zahlen in lokalisierte Währungszeichenfolgen.
C++: Verwenden Sie die Klasse „QLocale“
Verwenden Sie in C++ „ 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 Textzeichenfolgen
Verwenden Sie die Funktionen „ _NOOP “ (in QML) und die Makros „ _NOOP “ (in C++), um übersetzbare Zeichenfolgenliterale für die Extraktion durch das Tool „ lupdate “ zu kennzeichnen.
QML: Verwenden Sie _NOOP-Funktionen
Verwenden Sie in QML die folgenden Funktionen, um übersetzbare Zeichenfolgen zu markieren:
Wenn der Benutzer die Systemsprache ohne Neustart ändert, werden die Zeichenfolgen in Arrays, Listenmodellen und anderen Datenstrukturen je nach System möglicherweise nicht automatisch aktualisiert. Um die Aktualisierung der Texte bei der Anzeige in der Benutzeroberfläche zu erzwingen, müssen Sie die Zeichenfolgen mit der Funktion „ QT_TR_NOOP() “ deklarieren. Wenn Sie anschließend die Objekte für die Anzeige befüllen, müssen Sie die Übersetzung für jeden Text explizit abrufen.
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++: Verwenden Sie _NOOP-Makros
Für übersetzbaren Text, der vollständig außerhalb einer Funktion steht, verwenden Sie die Makros ` QT_TR_NOOP()`, ` QT_TRID_NOOP()` und ` QT_TRANSLATE_NOOP()`, die sich zu dem reinen Text ohne Kontext auflösen.
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 Quellcode vor einer Zeichenfolge, die Sie als übersetzbar markieren, Kommentare hinzufügen, um deren Zweck zu verdeutlichen. Die Kommentare werden in die TS-Dateien aufgenommen, die Sie an den Übersetzer übermitteln.
Hinweis: Die TS-Dateien sind XML-Dateien, die die Quelltexte sowie Platz für den übersetzten Text enthalten. Die aktualisierten TS-Dateien werden in binäre Übersetzungsdateien konvertiert und als Teil der endgültigen Anwendung integriert.
QML: Verwenden Sie //: und //~
Im folgenden Codeausschnitt ist der Text in der Zeile „ //: “ der Hauptkommentar für den Übersetzer.
Der Text in der Zeile „ //~ “ enthält optionale Zusatzinformationen. Das erste Wort des Textes wird als zusätzliche Kennung im XML-Element der TS-Datei verwendet; stellen Sie daher sicher, dass das erste Wort nicht Teil des Satzes ist. Beispielsweise 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++: Verwenden Sie Kommentarzeichen
Um in C++ Kommentare hinzuzufügen, versehen Sie die „ tr() “-Aufrufe in Ihrem Code mit Kommentaren der Form „ //: “ oder markieren Sie den Anfang und das Ende des Kommentars.
In den folgenden Beispielen beziehen sich die Kommentare auf die Zeichenfolgen, die im Kontext des jeweiligen Aufrufs 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 der üblichen Dateiendung des Dateiformats, von dem das Feld abgeleitet ist), einem Bindestrich und dem eigentlichen Feldnamen in durch Unterstriche getrennter Notation bestehen. Bei der Speicherung in TS-Dateien bildet der Feldname zusammen mit dem Präfix „ extra- “ einen XML-Elementnamen. Der Feldinhalt wird XML-escaped, erscheint aber ansonsten unverändert als Inhalt des Elements. Sie können jeder Nachricht eine beliebige Anzahl eindeutiger Felder hinzufügen.
Beispiel:
//: This is a comment for the translator.
//~ loc-layout_id foo_dialog
//~ loc-blank False
//~ magic-stuff This might mean something magic.
QString text = MyMagicClass::tr("Sim sala bim.");Hinweis: Die Verwendung von Metastring-Kommentaren mit dem Schlüsselwort „ //= “ zum Festlegen von IDs für textbasierte Übersetzungen ist in Qt 6.10 veraltet und wird in den kommenden Versionen entfernt.
Sie können das Schlüsselwort TRANSLATOR für Übersetzerkommentare verwenden. Metadaten, die unmittelbar vor dem Schlüsselwort TRANSLATOR stehen, gelten für die gesamte TS-Datei.
Hinweis: Wenn die TS-Datei in Qt Linguist geöffnet wird, werden die mit //: gekennzeichneten Kommentare im Nachrichteneditor von Qt Linguist angezeigt. Die Texte, die mit den Notationen //~ bereitgestellt werden, sind hingegen Zusatzinformationen und werden ausschließlich in der TS-Datei generiert. Sie sind hauptsächlich für die Konvertierung in andere Formate vorgesehen und in Qt Linguist ausgeblendet.
Gruppierung von ID-basierten Übersetzungen
Sie können jeder ID-basierten Übersetzung eine Bezeichnung zuweisen, um ID-basierte Einträge großer Projekte in kleinere Gruppen zu organisieren.
Um einem ID-basierten Eintrag eine Bezeichnung zuzuweisen, fügen Sie einen Kommentar vom Typ „ //@ “ hinzu, in dem Sie die Bezeichnung angeben, zum Beispiel in C++:
//% "Open file"
//@ FileOperations
qtTrId("msg.open");Oder in QML:
//% "Open file"
//@ FileOperations
qsTrId("msg.open");Wenn Sie die TS-Datei in Qt Linguist, werden die ID-basierten Einträge mit demselben Label zusammengefasst, ähnlich wie textbasierte Einträge, die nach Kontext gruppiert werden. Alle Elemente ohne Label erscheinen unter „ <unnamed label> “.
Hinweis: Labelnamen haben keinen Einfluss auf die Suche oder die Eindeutigkeit: IDs bleiben global eindeutig und können weiterhin über ` qtTrId("msgid") ` geladen werden, ohne auf ein Label zu verweisen. Das Label-Tag dient lediglich der besseren Navigation für Übersetzer und verändert das Laufzeitverhalten nicht.
Identische Texte unterscheiden
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“ beispielsweise sowohl einen Schritt rückwärts als auch die der Vorderseite gegenüberliegende Seite eines Objekts. Sie müssen dem Übersetzungssystem diese beiden unterschiedlichen Bedeutungen mitteilen, damit der Übersetzer zwei separate Übersetzungen erstellen kann.
QML: Fügen Sie einen Disambiguator zu `qsTr()` hinzu
Fügen Sie in QML eine Zeichenfolge zur Unterscheidung als zweiten Parameter der Funktion „ qsTr() “ hinzu.
Im folgenden Codeausschnitt unterscheidet die ID „ not front “ diesen „Back“- Text vom „Back“-Text für das Zurückgehen:
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()
In C++ übergeben Sie bei dem Aufruf von ` tr()` eine Zeichenfolge zur Eindeutigkeitssicherung.
Im folgenden Codeausschnitt unterscheidet der 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 gängigsten 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 anzufordern, die jedem Tastaturkürzel zugeordnet ist.
Verwenden Sie für benutzerdefinierte Tastenkombinationen für Menschen lesbare Zeichenfolgen wie „Strg+Q “ oder „Alt+F“. Diese können Sie in die entsprechenden Tastenkombinationen für Sprecher verschiedener Sprachen übersetzen.
Wenn Sie Tastaturkürzel in Ihrer Anwendung fest einprogrammieren, können Übersetzer diese nicht überschreiben.
Wenn Sie Tastaturkürzel in Menüelementen und Schaltflächentexten verwenden, zeigt ein Mnemonikzeichen (durch Unterstreichung gekennzeichnet) an, dass das Drücken von Alt oder Strg zusammen mit dem unterstrichenen Zeichen dieselbe Aktion ausführt wie das Klicken auf das Menüelement oder das Drücken der Schaltfläche.
Beispielsweise verwenden Anwendungen häufig „F“ als Mnemonikzeichen im Menü „ File “ (Datei), sodass Sie entweder auf den Menüpunkt klicken oder Alt+F drücken können, um das Menü zu öffnen. Um das Mnemonikzeichen in der zu übersetzenden Zeichenfolge („Datei“) zu definieren, setzen Sie ein Und-Zeichen davor: „ "&File" “. Die Übersetzung der Zeichenfolge sollte ebenfalls ein Und-Zeichen 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“
Verwenden Sie in C++ die Objekte „ QAction “ und „ QKeySequence “, um die Tastenkombinationen festzulegen, die Aktionen auslösen:
exitAct = new QAction(tr("E&xit"), this);
exitAct->setShortcuts(QKeySequence::Quit);Die Übersetzungen der Tastaturkürzel sind dem „ QShortcut “-Kontext zugeordnet.
Verwenden Sie „Locale“, um die Lokalisierungsfunktionen zu erweitern
Möglicherweise sind für verschiedene geografische Regionen andere Grafiken oder Audiodateien besser geeignet.
Versuchen Sie generell, die Lokalisierung von Bildern zu vermeiden. Erstellen Sie Symbole, die weltweit geeignet sind, anstatt sich auf lokale Wortspiele oder weit hergeholte Metaphern zu verlassen. Möglicherweise müssen Sie jedoch die Bilder von nach links und rechts zeigenden Pfeilen für arabische und hebräische Sprachumgebungen umkehren.
„Locale“ ist einer der Standard-Dateiauswähler, sodass Sie mithilfe der Dateiauswahl je nach System-Locale unterschiedliche Bilder anzeigen können, die Sie als Ressourcen bereitstellen.
Die QML- und C++-Code-Beispiele in den folgenden Abschnitten gehen davon aus, dass Sie die folgenden Dateien in den Anwendungsressourcen bereitstellen und Sprach- und Ländercodes als Namen für die Unterordner verwenden:
images
├── language-icon.png
├── +en_GB
│ └── language-icon.png
└── +fi_FI
└── language-icon.pngQML: Bildquelle festlegen
Der folgende QML-Codeausschnitt zeigt, wie ein Symbolquellbild entsprechend der aktuellen Ländereinstellung ausgewählt wird:
icon.source: "qrc:/images/language-icon.png"C++: „QFileSelector“ verwenden
Der folgende C++-Codeausschnitt verwendet ` QFileSelector `, um entsprechend der Systemlokalisierung ein Sprachsymbol aus dem Ordner „ images “ auszuwählen:
const QFileSelector selector;
const QIcon languageIcon(selector.select(":/images/language-icon.png"));Übersetzung aktivieren
TS-Dateinamen müssen ISO-Sprach- und Ländercodes enthalten:
- „language“ ist ein ISO-639 -Sprachcode in Kleinbuchstaben.
- „country“ ist ein zweistelliger ISO-3166 -Ländercode in Großbuchstaben.
Beispielsweise legt „ qml_de.ts “ die Zielsprache auf Deutsch fest, und „ qml_de_CH.ts “ legt die Zielsprache auf Deutsch und das Zielland auf die Schweiz fest. Das Tool „ lrelease “ generiert QM-Dateien mit den Namen „ qml_de.qm “ und „ qml_de_CH.qm “, die die Anwendung je nach Systemlokalisierung lädt.
QML: Verwenden Sie QQmlApplicationEngine
Verwenden Sie in QML „ QQmlApplicationEngine “, um Übersetzungsdateien automatisch aus einem Unterverzeichnis namens „ i18n “ in dem Verzeichnis zu laden, das die Haupt-QML-Datei enthält. Die Namen der Übersetzungsdateien müssen das Präfix „ qml_ “ haben. Beispiel: „ qml_en_US.qm “. In den folgenden CMake-Codeausschnitten erfahren Sie, wie Sie eine mehrsprachige App einrichten:
...
find_package(Qt6 6.5 REQUIRED COMPONENTS Quick LinguistTools)
qt_standard_project_setup(REQUIRES 6.5 I18N_TRANSLATED_LANGUAGES ja_JP)
qt_add_qml_module(appmultilingual_demo
URI multilingual_demo
QML_FILES
Main.qml
)
qt_add_translations(appmultilingual_demo
TS_FILE_BASE qml
TS_FILE_DIR i18n
RESOURCE_PREFIX /qt/qml/multilingual_demo/i18n
)
...Anwendungen laden Übersetzungen neu, wenn sich der Wert der Eigenschaft „ QJSEngine::uiLanguage “ oder „ Qt.uiLanguage “ ändert. Der folgende Codeausschnitt ändert die Sprache dynamisch, wenn der Benutzer auf die Schaltfläche klickt:
Button {
anchors.centerIn: parent
text: qsTr("Translate")
onClicked: {
Qt.uiLanguage = Qt.uiLanguage === "en" ? "ja" : "en"
}
}C++: Verwenden Sie QTranslator
In C++ müssen die Namen der TS-Dateien den Anwendungsnamen enthalten. Zum Beispiel „ app_de_DE.ts “.
In der Regel sieht die Funktion ` main() ` Ihrer Qt-C++-Anwendung wie folgt 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, rufen zur Laufzeit über ` load ` eine Übersetzung entsprechend der UI-Anzeigelokalisierung des Benutzers ab und binden das Übersetzerobjekt in die Anwendung ein.
Vorbereitung auf dynamische Sprachwechsel
Sowohl ` Qt Widgets ` als auch ` Qt Quick ` nutzen das Qt-Ereignissystem, um Klassen über Übersetzungsänderungen zu informieren.
LanguageChange Ereignisse werden ausgelöst, wenn Sie die Funktion ` QCoreApplication::installTranslator()` verwenden, um eine neue Übersetzung zu installieren. Andere Anwendungskomponenten können zudem Widgets oder vom Typ ` Item ` abgeleitete QML-Typen dazu zwingen, sich selbst zu aktualisieren, indem sie ` LanguageChange `-Ereignisse an diese senden.
Standardmäßig werden „ LanguageChange “-Ereignisse an alle Fenster der obersten Ebene weitergeleitet und von dort aus durch den gesamten Baum der Widgets oder von „Item“ abgeleiteten QML-Typen weitergeleitet.
Qt Widgets: „changeEvent“ überschreiben
Der Standard-Ereignis-Handler für Unterklassen von ` QWidget ` reagiert auf das ` QEvent::LanguageChange `-Ereignis und ruft bei Bedarf die Funktion ` changeEvent() ` auf.
Damit Qt Widgets Änderungen an den installierten „ QTranslator “-Objekten erkennen, implementieren Sie die Funktion ` changeEvent()` des Widgets neu, um zu prüfen, ob es sich um ein „ LanguageChange “-Ereignis handelt, und aktualisieren Sie den von den Widgets angezeigten Text mithilfe der Funktion ` tr()`. Beispiel:
void MyWidget::changeEvent(QEvent *event)
{
if (event->type() == QEvent::LanguageChange) {
titleLabel->setText(tr("Document Title"));
...
okPushButton->setText(tr("&OK"));
} else
QWidget::changeEvent(event);
}Bei Verwendung von „ Qt Widgets “-Designer-UI-Dateien (.ui) und „ uic “ können Sie die neuen Übersetzungsdateien einlesen 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 weiterzuleiten, rufen Sie die Standardimplementierung der Funktion auf.
Die Liste der installierten Übersetzer kann sich als Reaktion auf ein „ LocaleChange “-Ereignis ändern, oder die Anwendung stellt möglicherweise eine Benutzeroberfläche bereit, über die der Benutzer die aktuelle Anwendungssprache ändern kann.
QML: Ereignis überschreiben für von `Item` abgeleitete Typen
Bei einfachen QML-Anwendungen ohne benutzerdefinierte, in C++ registrierte Typen reicht die Verwendung von `QQmlApplicationEngine` aus, 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 lösen Sie darin das Änderungssignal der Eigenschaft aus (oder rufen Sie bei bindbaren Eigenschaften ` notify ` 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);
}
};Dadurch wird sichergestellt, dass jede Bindung in QML, in der die Eigenschaft verwendet wird, neu ausgewertet wird und die Sprachänderung berücksichtigt.
Generische, von `QObject` abgeleitete Klassen: Verwenden Sie Ereignisfilter
Einige Klassen leiten sich weder von ` QWidget ` noch von ` QQuickItem` ab, müssen aber möglicherweise dennoch Ereignisse zur Sprachänderung verarbeiten. In diesem Fall installieren Sie einen Ereignisfilter für ` QCoreApplication`.
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 erforderlich sein, wenn die Klasse übersetzte Zeichenfolgen bereitstellt, die später in einer Benutzeroberfläche angezeigt werden (beispielsweise bei einem benutzerdefinierten ` 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.
Weitere Überlegungen zum C++-Code
Die folgenden Abschnitte enthalten weitere Informationen zur Verwendung der Qt-C++-Klassen und -Funktionen in übersetzbaren Anwendungen:
- Verwenden Sie QString für alle für den Benutzer sichtbaren Texte
- Definieren Sie einen Übersetzungskontext
- Übersetzen Sie Nicht-Qt-Klassen
- Übersetzen von Text außerhalb einer QObject-Unterklasse
Verwenden Sie QString für alle für den Benutzer sichtbaren Texte
QString verwendet intern die Unicode-Kodierung, sodass Sie mit den gewohnten Textverarbeitungsoperationen alle Sprachen der Welt transparent verarbeiten können. Da zudem alle Qt-Funktionen, die dem Benutzer Text anzeigen, ein ` QString `-Objekt als Parameter verwenden, entsteht kein Konvertierungsaufwand bei der Umwandlung von ` char * ` in ` QString `.
Einen Übersetzungskontext definieren
Der Übersetzungskontext für „ QObject “ und jede Unterklasse von „ QObject “ ist der Klassenname selbst. Wenn Sie eine Unterklasse von „ QObject “ erstellen, verwenden Sie das Makro „ Q_OBJECT “ in der Klassendefinition, um den Übersetzungskontext zu überschreiben. Das Makro setzt den Kontext auf den Namen der Unterklasse.
Die folgende Klassendefinition enthält beispielsweise das Makro „ Q_OBJECT “ und implementiert eine neue Funktion „ tr() “, die den Kontext „ MainWindow “ verwendet:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow();
...Wenn Sie „ Q_OBJECT “ in einer Klassendefinition nicht verwenden, wird der Kontext von der Basisklasse geerbt. Da beispielsweise alle auf „ QObject “ basierenden Klassen in Qt einen Kontext bereitstellen, verwendet eine neue Unterklasse von „ QWidget “, die ohne das Makro „ Q_OBJECT “ definiert wurde, den Kontext „ QWidget “, wenn Sie deren Funktion „ tr() “ aufrufen.
Übersetzung von Nicht-Qt-Klassen
Für Klassen, die nicht von ` QObject ` erben oder das Makro ` Q_OBJECT ` verwenden, müssen Sie für ` lupdate ` zusätzliche Informationen zu den Zeichenfolgen bereitstellen. Um einer Nicht-Qt-Klasse Übersetzungsunterstützung hinzuzufügen, können Sie das Makro ` Q_DECLARE_TR_FUNCTIONS()` verwenden. Beispiel:
class MyClass
{
Q_DECLARE_TR_FUNCTIONS(MyClass)
public:
MyClass();
...
};Dadurch erhält die Klasse die Funktionen „ tr()“, mit denen Sie die mit der Klasse verbundenen Zeichenfolgen übersetzen können, und „ lupdate “ kann übersetzbare Zeichenfolgen im Quellcode finden.
Alternativ können Sie die Funktion ` QCoreApplication::translate()` mit einem bestimmten Kontext aufrufen, den lupdate und Qt Linguist erkennen.
Text außerhalb einer QObject-Unterklasse übersetzen
Befindet sich der angegebene Text nicht in einer Memberfunktion einer „ QObject “-Unterklasse, 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);
}© 2026 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.