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.
QtWS25 Last Chance

Another "change qt application language at runtime" thread.

Scheduled Pinned Locked Moved General and Desktop
50 Posts 4 Posters 31.9k Views
  • 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.
  • BilbonSacquetB Offline
    BilbonSacquetB Offline
    BilbonSacquet
    wrote on last edited by
    #28

    Sorry, regarding the way I do multiple inheritence, you could find help in the Qt documentation: "Using a Design UI File in Your Application", pay a look to the last chapter:"Automatic Connections".

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

      The link you gave me says

      @QMetaObject::connectSlotsByName(this);@

      Gives me this error: “'QObject' is an ambiguous base of 'MyWidget'”

      • But you use QWidget:: Is there a reason for this?
      1 Reply Last reply
      0
      • G Offline
        G Offline
        goetz
        wrote on last edited by
        #30

        You inherit twice from QObject:

        @
        class MyTranslation : public QObject
        class MyWidget: public QWidget, public Ui::MyWidget, public MyTranslation<MyWidget>
        @

        So you inherit from QObject via QWidget (which is a QObject subclass) and via MyTranslation. This is not supported!

        http://www.catb.org/~esr/faqs/smart-questions.html

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

          BilbonSacquet you must have met this problem then?

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

            It's supported, you should simply take care of the conflict. But we could do it through delegations (I take in consideration all what we say):

            @
            #include <QtCore/QObject>

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

            public:
            MyTranslator(T* widget)
            : m_t(widget)
            {
            m_t->installEventFilter(this);
            }

            ~MyTranslator() 
            { 
                m_t->removeEventFilter(this); 
            }
            
            bool eventFilter(QObject *obj, QEvent *event)
            {
                Q_UNUSED(obj);
            
                if (m_t && event->type() == QEvent::LanguageChange)
                { 
                    // not automatally retranslation
                    m_t->T:translationChanged();
                }
                return false;
            }
            

            };

            #include <QtGui/QWidget>

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

            class MyWidget: public QWidget
            {
            Q_OBJECT

            public:
                MyWidget(QWidget* parent = 0)
                : QWidget(parent), 
                  m_translator(this)
                {
                    ui.setupUi(this);
                }
            
                virtual ~MyWidget() {}
            
                virtual void translationChanged()
                {
                    ui.restranslateUi();
            
                    qWarning() << "translator changed";
                }
            
            private:
                MyTranslator<MyWidget> m_translator;
                Ui::MyWidget ui;
            

            };
            @

            1 Reply Last reply
            0
            • G Offline
              G Offline
              goetz
              wrote on last edited by
              #33

              The "docs of moc":http://doc.qt.nokia.com/4.7/moc.html#multiple-inheritance-requires-qobject-to-be-first state it clearly:

              bq. Multiple Inheritance Requires QObject to Be First
              If you are using multiple inheritance, moc assumes that the first inherited class is a subclass of QObject. Also, be sure that only the first inherited class is a QObject.
              [emphasis by me, Volker]

              http://www.catb.org/~esr/faqs/smart-questions.html

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

                But now you don't inherit from MyTranslator, in the code you just postet?

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

                  Yes, I do both variation (just for you)!

                  The inherited and the delegated! Both are correct ... just now choose the one you want :).

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

                    Even the multiple inherited is correct because (to take the sitation of Volker) the first inherited IS a QObject (QWidget is a QObject)!! :)

                    1 Reply Last reply
                    0
                    • G Offline
                      G Offline
                      goetz
                      wrote on last edited by
                      #37

                      [quote author="BilbonSacquet" date="1321629111"]Even the multiple inherited is correct because (to take the sitation of Volker) the first inherited IS a QObject (QWidget is a QObject)!! :)[/quote]

                      Don't pick what you want to have and leave out the annoying details that make your design fail!

                      bq. Also, be sure that only the first inherited class is a QObject.

                      http://www.catb.org/~esr/faqs/smart-questions.html

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

                        Both was tested and works! :)

                        But I give you right, it's never good to multiple inherits QObject. So that's why I rewrite it with a delegation.

                        But in fact to achieve some automatical translation mechanism (without to hack the current implementation) we need in QObject a callback like in widget for paint event with paintEvent().

                        1 Reply Last reply
                        0
                        • G Offline
                          G Offline
                          goetz
                          wrote on last edited by
                          #39

                          working != officially supported

                          And the state of "working" may vary between platforms and compilers.

                          And I don't get the purpose of the template class at all. It calls retranslateUi in the templates argument, so it has to be implemented in all the widgets. Where's the big difference and the coder's savings to implementing changeEvent? On will have to touche every widget class eventually, so why not make it the "standard" way?

                          http://www.catb.org/~esr/faqs/smart-questions.html

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

                            You have right not much, I have tried to make something lighter through template (like he suggests) and to have not to write too much code. :)

                            For the main problem, you should retranslate anyway yourself the 'dynamical' strings.

                            1 Reply Last reply
                            0
                            • G Offline
                              G Offline
                              goetz
                              wrote on last edited by
                              #41

                              There is no significant difference in implementing changeEvent() or translationChanged() - both contain basically the same code regarding the translation (calling ui.retranslateUi() and possibly some manual code). There's a minimal overhead with the event handling in changeEvent().

                              Just a matter of KISS - no more complex than needed :)

                              http://www.catb.org/~esr/faqs/smart-questions.html

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

                                I want to thank you for helping me out! I am very grateful.

                                I've decided to follow Volkers advice and do it the "official" way. I'm sorry BilbonSacquet - I am really grateful for your work!

                                I'm trying to follow the example from the link I give in #0 again. I have a few questions though.
                                How/where is the "language name" added to the actual Ui, enabling the user to choose between available languages? I'm not sure what the component in the example is, but I'm gonna use a qtablewidget to hold my language names. Is this done the same way as in the example?

                                Thank you so much for your time!

                                1 Reply Last reply
                                0
                                • G Offline
                                  G Offline
                                  goetz
                                  wrote on last edited by
                                  #43

                                  In the wiki article, the available languages are determined by the available translation files (.qm) in method createLanguageMenu. You can go this way too, or implement your own algorithm, of course.

                                  http://www.catb.org/~esr/faqs/smart-questions.html

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

                                    I'm now able to change the language on the static strings made in my designer.

                                    I'm not sure how to change it for all the strings written in code. I thought it would be done the same way as the designer strings. When changing the language, the dynamic string changes to the content of the string in the designer. This is not intended of course - instead it should get the translation from the .qm file.

                                    I'm also a bit confused concerning a line in the wiki article:

                                    @void MainWindow::loadLanguage(const QString& rLanguage)
                                    {
                                    if(m_currLang != rLanguage)
                                    {
                                    m_currLang = rLanguage;
                                    QLocale locale = QLocale(m_currLang);
                                    QLocale::setDefault(locale);
                                    QString languageName = QLocale::languageToString(locale.language());
                                    switchTranslator(m_translator, QString("TranslationExample_%1.qm").arg(rLanguage));
                                    switchTranslator(m_translatorQt, QString("qt_%1.qm").arg(rLanguage)); <------------
                                    ui.statusBar->showMessage(tr("Current Language changed to %1").arg(languageName));
                                    }
                                    }@

                                    The line marked with an arrow is the one confusing me. My guess is that it has something to do with my mentioned problem (Change language for dynamic strings)?

                                    Thank you for your time!

                                    EDIT:
                                    I of course wrap my strings in tr().

                                    When the changeEvent is called with a LanguageChange event, @ui.retranslateUi(this);@ is "run". When looking into this function, it seems that the application indeed just takes the string written in the designer.

                                    How do I get the string from my .qm file instead?

                                    EDIT2:
                                    I just wanted to add that my application is made using a model-view-controller pattern. All my Ui's are initialized in the controller class. Upon initialization the Ui's get a title. I don't know if this info helps?

                                    Please, I'm totally locked here :(

                                    1 Reply Last reply
                                    0
                                    • G Offline
                                      G Offline
                                      goetz
                                      wrote on last edited by
                                      #45

                                      The strings in ui.retranslateUi() are taken from the .qm file.
                                      Of course, they contain only the strings in the form itself. Everything else - i.e. the strings used programmatically in your code - must be retranslated in the event too.

                                      So, if you have somewhere in your C++ code a line like this:

                                      @
                                      ui->infoLabel->setText(tr("Let's go this way"));
                                      @

                                      You will have to add to the event handler that very same line too.

                                      There is no automatic retranslation in Qt! You must do this manually on a language change. ui.retransalateUi() does exactly this - it's just for convenience that the code is generated by uic.

                                      The line marked with an arrow just loads the Qt translations. If you omit that, the system messages (like in file dialogs etc.) are not translated.

                                      Additionally, I strongly recommend reading thoroughly through the docs of the translation and internationalization system in order to understand what's going on and how Qt computes the translated strings:

                                      • "Internationalization with Qt":/doc/qt-4.7/internationalization.html
                                      • "Qt Linguist for Programmers":/doc/qt-4.7/linguist-programmers.html
                                      • [[Doc:QTranslator]] API docs
                                      • "Writing Source Code for Translation":/doc/qt-4.7/i18n-source-translation.html
                                      • The "Hello tr() example":/doc/qt-4.7/linguist-hellotr.html
                                      • The "I18N example":/doc/qt-4.7/tools-i18n.html

                                      http://www.catb.org/~esr/faqs/smart-questions.html

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

                                        Thank you for the reply.

                                        I just wanna illustrate my scenario:

                                        From menuList.cpp
                                        @MenuList::MenuList(QString title, , QWidget *parent) : QWidget (parent) {
                                        ui.setupUi(this);
                                        ui->infoLabel->setText(title);
                                        }@

                                        From controller.cpp
                                        @void Controller::initializeScreens() {
                                        mainMenuScreen = new MenuList(tr("Main menu"), ...);
                                        settingsMenuScreen = new MenuList(tr("Settings"), ...);
                                        }@

                                        I tried adding
                                        @ui->infoLabel->setText(title);@
                                        to the event handler (in the MenuList class) like you said, but I get nothing.

                                        Does it have something to do with me inserting 'title' instead of an actual string (like "textstring here")?

                                        I've already looked at many of the links you provided, but I will look again.

                                        Thanks!

                                        1 Reply Last reply
                                        0
                                        • G Offline
                                          G Offline
                                          goetz
                                          wrote on last edited by
                                          #47

                                          you must handle the language change in that class, that has the tr("xxx") for the string. You do not do it in the class that gets the already translated string. If the latter was true, you wouldn't have a ui.retranslateUi, but the QLabel would retranslate it's contents.

                                          http://www.catb.org/~esr/faqs/smart-questions.html

                                          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