Qt Linguist, dynamiczna zmiana języka

0

Napisałem prosty programik do zmiany języka na labelu utworzonym w QtDesignerze. Jednak po wybraniu z menu języka aplikacja nie reaguje, język się nie zmienia. (Aczkolwiek sloty i sygnały działają, bo qDebug() wyświetla poprawne napisy).

Używam Qt5, Ubuntu, wszystkie pliki są 1 katalogu. Cały projekt: http://www.speedyshare.com/r7Yvz/qt-pl-en.tar.gz

Przejrzałem forum i trafiłem na temat: http://4programmers.net/Forum/C_i_C++/219384-problem_z_wielojezycznoscia_w_qt

  1. Pliki *.qm są tam, gdzie mój plik wykonywalny (katalog debug ...), skopiowałem je tam
  2. qDebug("translation %d", ok); wyświetla mi 1, więc powinno byc ok, a jezyk dalej się nie zmienia ...

Moje wszystkie pliki:

.pro:

QT       += core gui
    
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    TARGET = qt_pl_en
    TEMPLATE = app
    
    
    SOURCES += main.cpp\
            mainwindow.cpp
    
    HEADERS  += mainwindow.h
    
    FORMS    += mainwindow.ui
    
    TRANSLATIONS += ic.ts
    TRANSLATIONS += se.ts

mainwindow.cpp

#include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include <QTranslator>
    #include <QDebug>
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        retranslate();
    
        QObject::connect(ui->action_Icelandic, SIGNAL(triggered()), this, SLOT(speakIcelandic()));
        QObject::connect(ui->action_Swedish, SIGNAL(triggered()), this, SLOT(speakSwedish()));
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    
    void MainWindow::changeEvent(QEvent* event)
    {
        if (event->type() == QEvent::LanguageChange)
        {
            // retranslate designer form
            ui->retranslateUi(this);
    
            // retranslate other widgets which weren't added in designer
            retranslate();
        }
    
        // remember to call base class implementation
        QWidget::changeEvent(event);
    }
    
    void MainWindow::retranslate()
    {
        ui->label->setText(QObject::tr("Hello, world! :-)"));
    }
    
    void MainWindow::speakSwedish()
    {
        QTranslator translator;
        translator.load("se.qm");
        qApp->installTranslator(&translator);
    
        ui->retranslateUi(this);
    
        qDebug() << "Swedish";
    }
    
    void MainWindow::speakIcelandic()
    {
        QTranslator translator;
        translator.load("ic.qm");
        qApp->installTranslator(&translator);
    
        ui->retranslateUi(this);
    
        qDebug() << "Icelandic";
    }

mainwindow.h

#ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
        
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private:
        Ui::MainWindow *ui;
    
        void retranslate();
        void changeEvent(QEvent* event);
    
    
    private slots:
    
        void speakSwedish();
        void speakIcelandic();
    };
    
    #endif // MAINWINDOW_H

main.cpp

#include "mainwindow.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
        
        return a.exec();
    }

ic.ts

<?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE TS>
    <TS version="2.0" language="en_EN">
    <context>
        <name>MainWindow</name>
        <message>
            <location filename="mainwindow.ui" line="14"/>
            <source>MainWindow</source>
            <translation type="unfinished"></translation>
        </message>
        <message>
            <location filename="mainwindow.ui" line="27"/>
            <location filename="mainwindow.cpp" line="13"/>
            <source>Hello, world! :-)</source>
            <translation type="unfinished">Halló, heimur! :-)</translation>
        </message>
        <message>
            <location filename="mainwindow.ui" line="42"/>
            <source>File</source>
            <translation type="unfinished"></translation>
        </message>
        <message>
            <location filename="mainwindow.ui" line="60"/>
            <source>&amp;Swedish</source>
            <translation type="unfinished"></translation>
        </message>
        <message>
            <location filename="mainwindow.ui" line="65"/>
            <source>&amp;Icelandic</source>
            <translation type="unfinished"></translation>
        </message>
    </context>
    </TS>

se.ts

<?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE TS>
    <TS version="2.0" language="en_EN">
    <context>
        <name>MainWindow</name>
        <message>
            <location filename="mainwindow.ui" line="14"/>
            <source>MainWindow</source>
            <translation type="unfinished"></translation>
        </message>
        <message>
            <location filename="mainwindow.ui" line="27"/>
            <location filename="mainwindow.cpp" line="13"/>
            <source>Hello, world! :-)</source>
            <translation type="unfinished">Hallå, världen! :-)</translation>
        </message>
        <message>
            <location filename="mainwindow.ui" line="42"/>
            <source>File</source>
            <translation type="unfinished"></translation>
        </message>
        <message>
            <location filename="mainwindow.ui" line="60"/>
            <source>&amp;Swedish</source>
            <translation type="unfinished"></translation>
        </message>
        <message>
            <location filename="mainwindow.ui" line="65"/>
            <source>&amp;Icelandic</source>
            <translation type="unfinished"></translation>
        </message>
    </context>
    </TS>

mainwindow.ui

 <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>MainWindow</class>
     <widget class="QMainWindow" name="MainWindow">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>400</width>
        <height>300</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>MainWindow</string>
      </property>
      <widget class="QWidget" name="centralWidget">
       <widget class="QLabel" name="label">
        <property name="geometry">
         <rect>
          <x>120</x>
          <y>80</y>
          <width>181</width>
          <height>17</height>
         </rect>
        </property>
        <property name="text">
         <string>Hello, world! :-)</string>
        </property>
       </widget>
      </widget>
      <widget class="QMenuBar" name="menuBar">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>400</width>
         <height>25</height>
        </rect>
       </property>
       <widget class="QMenu" name="menuFile">
        <property name="title">
         <string>File</string>
        </property>
        <addaction name="action_Swedish"/>
        <addaction name="action_Icelandic"/>
       </widget>
       <addaction name="menuFile"/>
      </widget>
      <widget class="QToolBar" name="mainToolBar">
       <attribute name="toolBarArea">
        <enum>TopToolBarArea</enum>
       </attribute>
       <attribute name="toolBarBreak">
        <bool>false</bool>
       </attribute>
      </widget>
      <widget class="QStatusBar" name="statusBar"/>
      <action name="action_Swedish">
       <property name="text">
        <string>&amp;Swedish</string>
       </property>
      </action>
      <action name="action_Icelandic">
       <property name="text">
        <string>&amp;Icelandic</string>
       </property>
      </action>
     </widget>
     <layoutdefault spacing="6" margin="11"/>
     <resources/>
     <connections/>
    </ui>
1

Problem jest prosty i wynika z tego jak zarządzasz tłumaczeniami!
Po pierwsze używasz obiektów automatycznych (zmiennych lokalnych), więc tłumaczenia ci wyparowują zaraz po tym jak je instalujesz (qt sprytnie zarządza QObject'ami więc nie prowadzi to do crush-a).
Po drugie należy po zmianie języka należy usunąć poprzednie tłumaczenie.
Po trzecie dobry kod powinien odseparować zmianę tłumaczeń od logiki aplikacji (osobna klasa do zarządzania tłumaczeniami).

0

Dzięki, rozwiązałem to tak:

void MainWindow::speakSwedish()
{
    qApp->removeTranslator(translator);

    bool ok = translator->load("se.qm");
    qDebug("translation %d", ok);
    qApp->installTranslator(translator);

    ui->retranslateUi(this);

    qDebug() << "Swedish";
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1