Qt JSON Benutzeroberfläche Übersetzen

Vitalij Mast · 4 November 2012

JSON steht für JavaScript Object Notation und ist ein Datenformat in lesbarer Textform, welches zum Abspeichern und einlesen von Eigenschaften bzw. Einstellungen sehr gut geeignet ist. Ich habe dieses Format erst vor kurzem kennengelernt und hab mir gedacht, dass man dieses als Sprachdatei mit dem Qt-Framework kombinieren kann. So hab ich mich mal ran gemacht und ein kleines Beispiel-Projekt erstellt. Um den Overhead der Webkit Bibliothek aus dem Weg zu gehen habe ich ein Standalone – Implementierung eines JSON Interpreters für Qt verwendet. Zu finden ist diese hier.

Das Programm selbst ist ein kleiner Rechner mit den Standardfunktionen wie Addition, Subtraktion, Multiplikation und Division; zusätzlich mit einer Einstellbaren Sprache. Verzeiht mir an dieser Stelle, wenn in den Sprachen irgendwelche Fehler zu finden sind, diese habe ich einfach von google Übersetzen lassen.

Wenn man sich das JSON Format mal näher anschaut sieht man relativ schnell wie das ganz Aufbaut ist.

{
"QJsonTranslatorExampleForm":
{
"QJsonTranslatorExample": "JsonTranslator Beispiel",
"&Exit": "B&eenden",
"&File": "&Datei",
"&Language": "&Sprache",
"Number One:": "Zahl Eins:",
"Number Two:": "Zahl Zwei:",
"Add": "Addieren",
"Subtract": "Subtrahieren",
"Multiply": "Multiplizieren",
"Divide": "Dividieren",
},
"QJsonTranslatorExample":
{
"Error": "Fehler",
"Invalid Input": "Falsche Eingabe",
"Result": "Ergebnis",
"The result value is: %1": "Das Ergebnis lautet: %1",
},
}

Die Struktur besteht aus zwei Teilen, links auf der Seite steht die Eigenschaft und rechts der Wert, jeweils mit zwei Anführungszeichen umhüllt. Des Weiteren kann der Wert selbst auch eine Struktur sein womit man eine Verschachtelung erreicht. In der Sprachdatei wird nun für jede Klasse welche irgendwelche Sprachelemente enthält so eine verschaltete Struktur erstellt.

Das Projekt enthält eine Klasse QJsonTranslator welche sich um das Laden von Sprachdateien und um das Übersetzen von Texten zuständig ist. Mit einem einfachen Aufruf von QJsonTranslator::loadLanguage() wird die Standardsprache geladen/verwendet. Der Aufruf diser sollte geschehen bevor irgendwelche Steuerelemente initialisiert werden. Optional kann man der Funktion einen Sprach Parameter vom Typ QLocale mitgeben. Der Pfad zu den Sprachdateien ist in der konstanten LANGUAGE_STD_PATH gespeichert und ist Standardmäßig auf ‚./lang‘ gesetzt. Die Dateiendung ist in der konstanten LANGUAGE_STD_SUFFIX hinterlegt und hat den Wert, wer hätte’s gedacht, .json.

Am Anfang des Programms wird mit der Funktion QJsonTranslatorExample::getAvailableLanguages() alle Verfügbaren Sprachdateien im Sprachordner gesucht und daraus ein Auswahlmenü generiert.

void QJsonTranslatorExample::getAvailableLanguages()
{
QLocale::Language cur_lang = QJsonTranslator::instance()->locale().language();
// Auswahlgruppe erstellen
QActionGroup *language_group = new QActionGroup(this);
// Alle json-Dateien im Sprachordner ./lang suchen
QDir dir(LANGUAGE_STD_PATH);
QStringList list = dir.entryList(QStringList() << QString("*%1").arg(LANGUAGE_STD_SUFFIX));
list.prepend("en.json");
// TODO: Eventuelle Duplikate entfernen.
// Für alle Sprachdateien ein Eintrag im Menü erstellen
for (int i = 0; i<list.count(); ++i)
{
// Den Namen der Sprache extrahieren
QString name = list[i].left(list[i].length()-QString(LANGUAGE_STD_SUFFIX).length());
QLocale locale(name);
QString nativ = locale.nativeLanguageName();
if (!nativ.isEmpty())
{
// Und falls gültig den Eintrag erstellen
QAction *action = new QAction(this);
action->setText(nativ);
// Benutzerdaten setzen, anhand diesen wird naher bei Auswahl die Sprachdatei geladen
action->setData(name);
action->setCheckable(true);
language_group->addAction(action);
// Wenn die Standartsprache geladen wurde, diese selektieren
if (cur_lang == locale.language())
action->setChecked(true);
}
}
// Liste dem Sprachmenü hinzufügen
ui.menu_Language->addActions(language_group->actions());
}

Wird nun einer dieser Spracheinträge per Menü vom Benutzer ausgewählt dann wird die entsprechende Datei geladen:

if (action->data().type() == QVariant::String)
{
QLocale newlanguage(action->data().toString());
QJsonTranslator::loadLanguage(&newlanguage);
}

Wenn die Sprache sich ändert wird an jedes Fenster ein changeEvent mit dem Parameter QEvent::LanguageChange gesendet. In diesem sollte man alle Steuerelemente mit dem neuen Text laden. Dies geschieht üblicherweise mit einem erneut zuweisen eines Textes. Zu Vereinfachung wird von QObject die Funktion QObject::tr(const char * sourceText) zur Verfügung gestellt, welche den sourceText an den Übersetzer, in meinem Fall die Klasse QJsonTranslator, übergibt und den Übersetzen Text zurückgibt.

Es gibt sicherlich noch ein paar Fehlerfälle, die es Abzufangen gilt, jedoch denke ich, dass das Prinzip klar sein sollte. Ansonsten schaut euch das Projekt bzw. den Source, bei Interesse, einfach hier an: QJsonTranslatorExample.

Twitter, Facebook