Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Another "change qt application language at runtime" thread.
Forum Updated to NodeBB v4.3 + New Features

Another "change qt application language at runtime" thread.

Scheduled Pinned Locked Moved General and Desktop
50 Posts 4 Posters 32.2k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    maxmotor
    wrote on last edited by
    #4

    But how should this change the fact that I don't get the translation from my .qm file?

    I'm confused...

    1 Reply Last reply
    0
    • BilbonSacquetB Offline
      BilbonSacquetB Offline
      BilbonSacquet
      wrote on last edited by
      #5

      I'm using myself a similar mechanism, the tr() will use the values of your new loaded dictionary.

      The values not set in designer will simply not appear in the retranslateUI(), you should simply clear the content of your label in the designer and use alternatively the translationChanged() to handle the non-static cases.

      1 Reply Last reply
      0
      • M Offline
        M Offline
        maxmotor
        wrote on last edited by
        #6

        Clearing the content of my label in the designer does not change anything it seems... The label just becomes empty when when trying to change language.

        Also, I'm sure what the translationChanged() function does? Doesn't it just overwrite whatever is in the label with "loaded" or "empty"?

        1 Reply Last reply
        0
        • BilbonSacquetB Offline
          BilbonSacquetB Offline
          BilbonSacquet
          wrote on last edited by
          #7

          Your code works perfectly, if you put in designer Textlabel as 'text' entry, the retranslatedUI() will simply find the equivalent in the string map (of your translator) and replace it and if none found he reset to the original value.

          Which means probably: it's missing the translation of your text?

          1 Reply Last reply
          0
          • M Offline
            M Offline
            maxmotor
            wrote on last edited by
            #8

            Oh but the label has dynamic content.

            The text is set when I create an instance of my ui. It takes a parameter called "title". It's this variable which should be translated and showed in the label.

            @TemplateUi::TemplateUi(QString title, QWidget *parent) :
            QWidget(parent) {
            ...
            }@

            1 Reply Last reply
            0
            • BilbonSacquetB Offline
              BilbonSacquetB Offline
              BilbonSacquet
              wrote on last edited by
              #9

              move this code from the c'tr to the 'famous' routine:

              void translationChanged() { mylabel->setText(tr("title")); }

              1 Reply Last reply
              0
              • BilbonSacquetB Offline
                BilbonSacquetB Offline
                BilbonSacquet
                wrote on last edited by
                #10

                what you dream is that Qt detects the 'title' with something like: @mylabel->setText(QApplication::translate(mylabel->text()));@

                Now remarks:

                • how he could find the translation if the text() is chinese?
                • how you will untranslate text like: tr("It will reboot in %1, please save your work!").arg(time) ?
                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  maxmotor
                  wrote on last edited by
                  #11

                  I want to translate my gui to danish. My default language is english.
                  I expect that Qt looks up my title ("Main menu") i my "dan.qm" file, and exchange it with the danish equivalent ("Hovedmenu").

                  When creating my screen/ui object, I do this:

                  @MenuList mainMenuScreen = new MenuList(tr("Main menu"), &mainMenuListVector);@

                  The first parameter is the title.

                  1 Reply Last reply
                  0
                  • BilbonSacquetB Offline
                    BilbonSacquetB Offline
                    BilbonSacquet
                    wrote on last edited by
                    #12

                    This all should be done in 3 parts:

                    a) Application
                    @
                    class MyApp
                    {
                    QTranslator m_translator;

                    public:
                    MyApp()
                    {
                    installTranslator(&m_translator);
                    }
                    MyApp::changeTranslation()
                    {
                    m_translator.load(QFileDialog::getOpenFileName());//here complete ()
                    }
                    };
                    @

                    b) make automatical response to LanguageChange message
                    @
                    class MyWidget : public QWidget, public Ui::MyWidget
                    {
                    QLable* m_mainMenuScreen;

                    public:
                    MyWidget(QWidget* parent)
                    {
                    setupUI(this);

                    m_mainMenuScreen = new MenuList(this, &mainMenuListVector); // don't care here with i18n
                    

                    }

                    protected:
                    virtual void translationChanged()
                    {
                    m_mainMenuScreen->setText(tr("Main menu"));
                    }

                    virtual void changeEvent(QEvent* event)
                    {
                    if (event->type() == QEvent::LanguageChange)
                    {
                    // retranslate designer form
                    ui.retranslateUi(this);

                        // not automatally retranslation
                        translationChanged();
                    }
                    
                    // remember to call base class implementation
                    QWidget::changeEvent(event);
                    

                    }
                    };
                    @

                    C) Now the goal is to make all this simplier, because of course it's not confortable to have to create manually for each widget all the routine. An idea is to inherit your own interface that you construct too in the constructor, this interface could install an event filter, here my quick and dirty and fast solution, not simply copy, check more the ideas:

                    @
                    template <class T>
                    class MyTranslation : public QObject
                    {
                    T* m_t;

                    public:
                    MyTranslation() : m_t(0) {}
                    ~MyTranslation() { if (m_t) m_t->QWidget::removeEventFilter(this); m_t = 0; }

                    void installTranslator(T* t) { m_t = t; m_t->QWidget::installEventFilter(this); }
                    

                    protected:
                    virtual void translationChanged() {}

                    bool eventFilter(QObject *obj, QEvent *event)
                    {  
                        if (m_t && event->type() == QEvent::LanguageChange)
                        {
                            // retranslate designer form
                            m_t->retranslateUi(this);
                    
                            // not automatally retranslation
                            translationChanged();
                        }
                        return false;
                    }
                    

                    };

                    class MyWidget : public QWidget, public Ui::MyWidget, public MyTranslation<MyWidget>
                    {
                    QLabel* m_mainMenuScreen;

                    public:
                    MyWidget(QWidget* parent) : QWidget(parent)
                    {
                    // construct
                    setupUI(this);
                    m_mainMenuScreen = new QLabel(this); // don't care here with i18n

                        installTranslator(this);
                    }
                    

                    protected:
                    virtual void translationChanged()
                    {
                    m_mainMenuScreen->setText(QWidget::tr("Main menu"));
                    }
                    };
                    @

                    1 Reply Last reply
                    0
                    • M Offline
                      M Offline
                      maxmotor
                      wrote on last edited by
                      #13

                      Thanks a lot for your replies BilbonSacquet.

                      I'm afraid I'm rather thickheaded...

                      You make me very confused. In your previous post - the goal for me is to make it like shown in c), right? a) and b) are what? Just to show the difference?

                      So in c) you tell me that all my screen widgets, should inherit from this MyTranslation interface? And why inherit from Ui::MyWidget? I just don't get it.

                      And what about the EventFilter - what is that for?

                      My brain is soon gonna pop out of my skull.

                      Can you, or anyone else, explain it to me in other words? Or just spell it out more.

                      I'm sorry :(

                      But thank you so much for your time!

                      1 Reply Last reply
                      0
                      • BilbonSacquetB Offline
                        BilbonSacquetB Offline
                        BilbonSacquet
                        wrote on last edited by
                        #14

                        ok, I go perhaps too fast, I'm stressed right now with work and I will to help the directest way possible. But that's my bad.

                        That's true a) b) is just to explain the steps ... and c) the solution.

                        Yes, all widget which needs translation should inherits this class, that's necessary to take the message QEvent::LanguageChange and to make 'automatically' callback the translation functions. The event filter is necessary because the template MyTranslation doesn't inherit of the widget (it's just an QObject) function like event().

                        The message LanguageChange cycle is now:
                        app -> MyWidget::event() -> MyTranslator::eventFilter() -> MyWidget::Ui::MyWidget::retranslateUI() , MyWidget::translationChanged()
                        (if the function is redefined otherwise MyTranslator::translationChanged())

                        Now why I inherits from Ui::MyClass, you will get the information from the Qt help. But mainly it makes all simplier in the handle of your widgets: same interface, you have all your children direct, you could use the on_mywidget_signal() slots without to connect/disconnct anything.
                        What I need is that all the widget has the function retranslateUi() accessible in the interface to be called by the template.

                        I hope that I have helped you with the explanation and not make all darker like in the Morian mines :D

                        1 Reply Last reply
                        0
                        • M Offline
                          M Offline
                          maxmotor
                          wrote on last edited by
                          #15

                          Okay I'm trying to work my way through it.

                          I'm writing the MyTranslation class now, but I get some errors:

                          @template <class T>
                          class MyTranslation : public QObject
                          {
                          T* m_t; //<------------- "Type 'T' could not be resolved"

                          public:
                          MyTranslation() : m_t(0) {}
                          ~MyTranslation() { if (m_t) m_t->QWidget::removeEventFilter(this); m_t = 0; }
                          ...@

                          Do I need to include something in order to do this?

                          1 Reply Last reply
                          0
                          • BilbonSacquetB Offline
                            BilbonSacquetB Offline
                            BilbonSacquet
                            wrote on last edited by
                            #16

                            Now I have verified/compiled the prototype given, I had done an error m_t->retranslateUi(-his- m_t);

                            Translation template - MyTranslator.h:
                            @
                            #include <QtCore/QObject>

                            template <class T>
                            class MyTranslation : public QObject
                            {
                            T* m_t;

                            public:
                            MyTranslation() : m_t(0) {}
                            ~MyTranslation() { if (m_t) m_t->QWidget::removeEventFilter(this); m_t = 0; }

                            void installTranslator(T* t) { m_t = t; m_t->QWidget::installEventFilter(this); }
                            

                            protected:
                            virtual void translationChanged() {}

                            bool eventFilter(QObject *obj, QEvent *event)
                            { 
                                if (m_t && event->type() == QEvent::LanguageChange)
                                {
                                    // retranslate designer form
                                    m_t->retranslateUi(m_t);
                            
                                    // not automatally retranslation
                                    translationChanged();
                                }
                                return false;
                            }
                            

                            };
                            @

                            The widget - MyWidget.h:

                            @
                            #include <QtGui/QWidget>

                            #include <ui_MyWidget.h>
                            #include <MyTranslator.h>

                            class MyWidget: public QWidget, public Ui::MyWidget, public MyTranslation<MyWidget>
                            {
                            Q_OBJECT

                            public:
                                MyWidget(QWidget* parent = 0);
                                virtual ~MyWidget();
                            
                            protected:
                                virtual void translationChanged();
                            

                            };
                            @

                            The MyWidget.cpp:
                            @
                            #include "MyWidget.h"

                            MyWidget::MyWidget(QWidget* parent) : QWidget(parent)
                            {
                            setupUi(this);
                            installTranslator(this);
                            }

                            MyWidget::~MyWidget() {}

                            void MyWidget::translationChanged()
                            {
                            qWarning() << "translator changed";
                            }
                            @

                            And of course you need a MyWidget.ui with class MyWidget :) use the default widget. To make it faster I integrate on my current project, and redo a adapted copy/paste. It could have typos but should be ok now.

                            1 Reply Last reply
                            0
                            • M Offline
                              M Offline
                              maxmotor
                              wrote on last edited by
                              #17

                              Thank you, but I still get the error in the start when writing:

                              @T* m_t;@

                              1 Reply Last reply
                              0
                              • BilbonSacquetB Offline
                                BilbonSacquetB Offline
                                BilbonSacquet
                                wrote on last edited by
                                #18

                                hmm .. which compiler are you using ?

                                1 Reply Last reply
                                0
                                • M Offline
                                  M Offline
                                  maxmotor
                                  wrote on last edited by
                                  #19

                                  mingw

                                  1 Reply Last reply
                                  0
                                  • BilbonSacquetB Offline
                                    BilbonSacquetB Offline
                                    BilbonSacquet
                                    wrote on last edited by
                                    #20

                                    you could try to replace 'template <class T>' by 'template <typename T>'

                                    1 Reply Last reply
                                    0
                                    • M Offline
                                      M Offline
                                      maxmotor
                                      wrote on last edited by
                                      #21

                                      No change :(

                                      1 Reply Last reply
                                      0
                                      • BilbonSacquetB Offline
                                        BilbonSacquetB Offline
                                        BilbonSacquet
                                        wrote on last edited by
                                        #22

                                        and for no warnings compilation add: Q_UNUSED(obj); into the enventFilter()

                                        1 Reply Last reply
                                        0
                                        • M Offline
                                          M Offline
                                          maxmotor
                                          wrote on last edited by
                                          #23

                                          But the error happens before this? I have only written:

                                          @template <class T>
                                          class MyTranslation : public QObject
                                          {
                                          T* m_t;

                                          public:
                                          MyTranslation() : m_t(0) {}
                                          ~MyTranslation() { if (m_t) m_t->QWidget::removeEventFilter(this); m_t = 0; }
                                          };@

                                          And it gives the error...

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved