Sprache zur Laufzeit ändern

Nun möchten wir unser Program auch in verschiedenen Ländern verteilen dazu soll der Anwender seine Landes Sprache selbst auswählen können.

Hierbei hilft uns das programm kürzel tr() und der Qt Linguist.

Jeder QString der in ein tr eingefasst ist wird später mit dem Linguisten extrahiert so das man eine Übersetzung dafür eingeben kann, die dann über einen QTranslator im Programm eingefügt wird, doch dazu später mehr.

Die von uns erstellten Formulare form.ui und mainwindow.ui wurden automatisch mit dem tr Kürzel versehen man muss nur sicherstellen das man die funktion retranslateUi() aufruft.

schaut man sich die generierten files ui_mainwindow.h oder ui_form.h an sieht man in der Funktion retranslateUi(QMainwindow *Mainwindow) z.B folgendes

actionLaden->setText(QApplication::translate("MainWindow", "laden", 0, QApplication::UnicodeUTF8));

Was im Prinzip einem tr(„laden“) kürzel entspricht der Menüpunkt laden befindet sich Irgendwo in unserem Menübar.

Bei allen Texten die man selbst in den Code einfügt muss man jedoch auch selbst dafür sorge tragen, dass sie später vom Linguisten erkannt werden.

In unserem Beispiel gibt es Momentan leider keinen solchen Text, daher fügen  wir als Beispiel ein Label in unser mainwindow.ui ein.

neues label

Wir fügen dann noch in unseren TimerEvent  ein ui->label_2->setText() ein.

void MainWindow::timerEvent(QTimerEvent *event)
{
  QTime qtime = QTime::currentTime();
  QString stime = qtime.toString(Qt::LocalDate);
  ui->label->setText(stime);
  ui->label_2->setText(tr("das ist ein zu\nübersetzender Text"));<--- hier ist nun unser tr()
}

Macht zwar hier keinen richtigen Sinn verdeutlicht aber sehr gut die Funktionsweise des Translators. Denn jedesmal wenn der Text gesetzt wird, hier also jede Sekunde  wird er auch erst übersetzt. Bzw der übersetzte Text, von dem aktuell Installierten QTranslator, eingefügt. Im späteren Programmablauf sieht man diesen Text dann wie er sich nach einer Sekunde aktualisiert, zwischendrin sieht man den „Standard Text“ aus dem .ui File.

Anschließend benötigen wir noch eine Möglichkeit die Sprache einzustellen dafür verwende ich nun eine ComboBox:

combobox

hier kann man nun mit einem Doppelklick und das grüne Plus die gewünschten Sprachen eintragen zunächt einmal deutsch und english.

Wichtig ist unter Eigenschaften diese Texte nicht für die Übersetzung zu markieren. Da wir sie später verwenden wollen, um zu entscheiden welche Sprachdatei wir auswählen. Also nicht Übersetzen sonst führt das zur kompletten Verwirrung.

Jetzt benötigen wir noch einen QTranslator  dazu fügen wir in unsere mainwindow.h einen QTranslator ein und einen neuen Slot change_language

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "ui_form.h"
#include <QMainWindow>
#include <QTranslator> <------ hier die Klasse Qtranslator includen
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    QDialog *newform;
    Ui::Form Form;
    QString numbOne;
    QTranslator language_en; <------ hier eine Variable vom typ QTranslator anlegen.
protected:
    void timerEvent(QTimerEvent *event);
private slots:
    void on_actionSlider_triggered();
    void on_actionLaden_triggered();
    void on_actionSpeichern_triggered();
    void on_actionQt_Info_triggered();
void resetall();
void change_language(QString language); <--- unser neuer Slot change_language
};
#endif // MAINWINDOW_H

Diesen Slot fügen wir nun auch noch in unser mainwindow.cpp ein:

void MainWindow::change_language(QString language)
{
if (language=="deutsch")
{
    qApp->removeTranslator(&language_en); //die Ursprungssprache wird hergestellt
}
if (language=="english")
{
    language_en.load("Egal_en"); <--- Aufruf der .qm Datei wenn sich die Datei direkt im Buildpfad befindet
    qApp->installTranslator(&language_en); //die Englishe Translationsdatei wird geladen 
}
}

Zusätzlich benötigen wir noch einen connect der combobox auf unseren neuen Slot im Konstruktor MainWindow::MainWindow:

connect(ui->comboBox,SIGNAL(currentIndexChanged(QString)),this,SLOT (change_language(QString)));

So nun haben wir unser Programm schonmal vorbereitet auf eine Übersetzung nun benötigen wir nur noch die Übersetzte Textdatei dazu fügen wir in unser Egal.pro folgenden Eintrag hinzu:

TRANSLATIONS += Egal_en.ts

dieser Eintrag wird benötigt um eine Text-Datei für den Qt Linguist zu erzeugen. Nochmal neu Kompilieren nicht vergessen!

Anschließend gehen wir auf  Extras->Extern->Linguist->Übersetzungen aktualisieren und führen damit ein lupdate aus. Nun sollte ein Egal_en.ts file in unserem Projectordner erstellt worden sein. Diese öffnen wir nun mit dem Qt Linguist  (bei mir zu finden unter D:\tools\Qt\bin\linguist.exe)

linguist

Hier sehen wir nun unser Mainwindow.ui und Form.ui wieder es werden alle gefundenen Texte die zum übersetzen markiert wurden angezeigt.

Jetzt gehts ans übersetzen Englisch krieg ich grade noch freihand hin… 🙂 Also überall eine Übersetzung eintragen. Man kann die bereits Übersetzen Texte mit einem grünen Häckchen markieren, Texte die nicht Übersetzt werden sollen, einfach nix eintragen. Wenn wir fertig sind das Egal_en.ts file speichern.

Nun füren wir ein lrelease aus indem wir im Creator über Extras-> Extern->Linguist->Übersetzung freigeben gehen.

Es wird ein Egal_en.qm file erzeugt das einer Binärdatei entspricht die im Code eingebunden wird.  Diese müssen wir in das jeweilige Build Verzeichniss kopieren (Hier D:\Qt_uebung\Egal-build-desktop-Qt_4_8_1_for_Desktop_-_MSVC2008__Qt_SDK__Debug wenn wir uns im Debug befinden. Oder die bessere Alternative wir packen sie in eine Resourcendatei. Dazu erstellen wir mit Rechtsklick auf unser Project Egal.pro->Hinzufügen->Qt->Qt Resourcedatei, dann muss man noch einen Namen für die Resourcedatei eingeben z.B. sprachen.qrc. Haben wir die Datei erstellt wählen wir sie im Project Explorer mit Doppelklick aus und gehen auch hier auf hinzufügen den prefix setzen wir auf „/“ da wir kein Unterverzeichnis haben in dem sich unsere Sprachdatei befindet. Nochmals Hinzufügen->Datei hinzufügen und die Egal_en.qm Datei auswählen.

sprache resource

Jetzt muss man noch darauf achten das man den Pfad im Aufruf im Programm wenn man eine Resourcendatei verwendet auf :

language_en.load(":/Egal_en");<--- Aufruf der .qm Datei wenn sich die Datei in einer Resourcendatei befindet

ändern muss damit unsere .qm Datei auch gefunden wird.

Jetzt müssen wir nur noch dafür sorgen das nachdem wir die Neue Sprache eingestellt haben auch ein retranslateUi ausgeführt wird.

dazu erstellen wir einen Event Handler  changeEvent(QEvent *event) der Überprüft ob die Sprachdatei per removeTranslator oder installTranslator geändert wurde.

im mainwindow.h fügen wir unter protected: (ähnlich dem timerevent) unser changeEvent ein:

protected:
    void timerEvent(QTimerEvent *event);
    void changeEvent(QEvent *e); <---- Ein neuer Event Handler

In Mainwindow.cpp fügen wir nun ein:

void MainWindow::changeEvent(QEvent *e)
{
    switch (e->type()) 
    {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

Um das eingehende changeEvent zu unterscheiden, wir wollen momentan nur auf ein LanguageChange Event reagieren.

Starten wir jetzt das Programm und wechseln die Sprache auf english werden alle zur Übersetzung markierten Texte, für die eine Übersetzung im .ts file existiert,  ersetzt.

translated gui

Versuchen sie als Übung weitere Sprachen einzubauen. Man sollte hier darauf achten das man bei mehreren Sprachen besser eine eigene Sprachdatei für „deutsch“ erstellt und somit den removeTranslator durch einen installTranslator(deutscheSprache) ersetzt. Oder man muss sich merken welcher Translator gerade installiert ist um auch den richtigen wieder zu removen.