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. Dynamic retranslation without reimplementing the changeEvent in every window/widget
Forum Update on Monday, May 27th 2025

Dynamic retranslation without reimplementing the changeEvent in every window/widget

Scheduled Pinned Locked Moved Solved General and Desktop
16 Posts 4 Posters 1.5k 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.
  • C Offline
    C Offline
    Christian Woznik
    wrote on last edited by
    #1

    I have a fairly big and comprehensive application that consists of a few dozent windows, custom widgets and dialogs that should allow dynamic retranslation as per customer request.

    It all works fine however having to reimplement the changeEvent in every single class just feels wrong to me. However I also have no idea how to really do it. I thought about creating a custom widget which is used for inheritance that just calls a pure virtual function but then I do not really save a lot of code as I have to reimplement that function in every new class.

    Is there any better way to do it?

    My first idea:

    #ifndef MYBASEWIDGET_H
    #define MYBASEWIDGET_H
    
    #include <QWidget>
    #include <QEvent>
    
    class MyBaseWidget : public QWidget
    {
            Q_OBJECT
        public:
            explicit MyBaseWidget(QWidget *parent = nullptr);
    
        protected:
            void changeEvent(QEvent * event) override;
    
            virtual void updateUI(void)=0;
    
        signals:
    
    };
    
    #endif // MYBASEWIDGET_H
    
    
    #include "mybasewidget.h"
    
    MyBaseWidget::MyBaseWidget(QWidget *parent)
        : QWidget{parent}
    {
    
    }
    
    void MyBaseWidget::changeEvent(QEvent * event)
    {
      // In the case of events changing the application language
      if (event->type() == QEvent::LanguageChange) {
        updateUI();
      }
    
      QWidget::changeEvent(event);
    }
    
    
    #ifndef MYDERIVEDFORMULARWIDGET_H
    #define MYDERIVEDFORMULARWIDGET_H
    
    #include "mybasewidget.h"
    
    namespace Ui {
        class MyDerivedFormularWidget;
    }
    
    class MyDerivedFormularWidget : public MyBaseWidget
    {
            Q_OBJECT
    
        public:
            explicit MyDerivedFormularWidget(QWidget *parent = nullptr);
            ~MyDerivedFormularWidget();
    
        protected:
            void updateUI(void) override;
    
        private:
            Ui::MyDerivedFormularWidget *ui;
    };
    
    #endif // MYDERIVEDFORMULARWIDGET_H
    
    
    #include "myderivedformularwidget.h"
    #include "ui_myderivedformularwidget.h"
    
    MyDerivedFormularWidget::MyDerivedFormularWidget(QWidget *parent) :
        MyBaseWidget(parent),
        ui(new Ui::MyDerivedFormularWidget)
    {
        ui->setupUi(this);
    }
    
    MyDerivedFormularWidget::~MyDerivedFormularWidget()
    {
        delete ui;
    }
    
    void MyDerivedFormularWidget::updateUI(void)
    {
        ui->retranslateUi(this);
    }
    
    
    JonBJ 1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by VRonin
      #3

      Macro time!

      #define MAKE_TRANSLATABLE(BaseClass) \
          protected: \
          void changeEvent(QEvent * event) override{ \
              if (event->type() == QEvent::LanguageChange) \
                  ui->retranslateUi(this); \
              BaseClass::changeEvent(event); \
          }
      #define MAKE_TRANSLATABLE_F(BaseClass, TranslateMethod) \
          protected: \
          void changeEvent(QEvent * event) override{ \
              if (event->type() == QEvent::LanguageChange) \
                  TranslateMethod(); \
              BaseClass::changeEvent(event); \
          }
      
      class TranslatableWidget : public QWidget{
          MAKE_TRANSLATABLE(QWidget)
      };
      
      class TranslatableCustomWidget : public QWidget{
          MAKE_TRANSLATABLE_F(QWidget,customRetranslateMethod)
      protected:
          void customRetranslateMethod();
      };
      

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      C 1 Reply Last reply
      2
      • C Christian Woznik

        I have a fairly big and comprehensive application that consists of a few dozent windows, custom widgets and dialogs that should allow dynamic retranslation as per customer request.

        It all works fine however having to reimplement the changeEvent in every single class just feels wrong to me. However I also have no idea how to really do it. I thought about creating a custom widget which is used for inheritance that just calls a pure virtual function but then I do not really save a lot of code as I have to reimplement that function in every new class.

        Is there any better way to do it?

        My first idea:

        #ifndef MYBASEWIDGET_H
        #define MYBASEWIDGET_H
        
        #include <QWidget>
        #include <QEvent>
        
        class MyBaseWidget : public QWidget
        {
                Q_OBJECT
            public:
                explicit MyBaseWidget(QWidget *parent = nullptr);
        
            protected:
                void changeEvent(QEvent * event) override;
        
                virtual void updateUI(void)=0;
        
            signals:
        
        };
        
        #endif // MYBASEWIDGET_H
        
        
        #include "mybasewidget.h"
        
        MyBaseWidget::MyBaseWidget(QWidget *parent)
            : QWidget{parent}
        {
        
        }
        
        void MyBaseWidget::changeEvent(QEvent * event)
        {
          // In the case of events changing the application language
          if (event->type() == QEvent::LanguageChange) {
            updateUI();
          }
        
          QWidget::changeEvent(event);
        }
        
        
        #ifndef MYDERIVEDFORMULARWIDGET_H
        #define MYDERIVEDFORMULARWIDGET_H
        
        #include "mybasewidget.h"
        
        namespace Ui {
            class MyDerivedFormularWidget;
        }
        
        class MyDerivedFormularWidget : public MyBaseWidget
        {
                Q_OBJECT
        
            public:
                explicit MyDerivedFormularWidget(QWidget *parent = nullptr);
                ~MyDerivedFormularWidget();
        
            protected:
                void updateUI(void) override;
        
            private:
                Ui::MyDerivedFormularWidget *ui;
        };
        
        #endif // MYDERIVEDFORMULARWIDGET_H
        
        
        #include "myderivedformularwidget.h"
        #include "ui_myderivedformularwidget.h"
        
        MyDerivedFormularWidget::MyDerivedFormularWidget(QWidget *parent) :
            MyBaseWidget(parent),
            ui(new Ui::MyDerivedFormularWidget)
        {
            ui->setupUi(this);
        }
        
        MyDerivedFormularWidget::~MyDerivedFormularWidget()
        {
            delete ui;
        }
        
        void MyDerivedFormularWidget::updateUI(void)
        {
            ui->retranslateUi(this);
        }
        
        
        JonBJ Online
        JonBJ Online
        JonB
        wrote on last edited by
        #2

        @Christian-Woznik
        There may well be a better way (I don't use translation). But in general in Qt if you want to do something to every widget instead of hooking onto each one (e.g. changeEvent()) one implements bool QObject::eventFilter(QObject *watched, QEvent *event) or maybe bool QObject::event(QEvent *e). My understanding is you can do this on some top-level widget (window/dialog/main window/whatever) and it will see all events that are destined for descendent widgets.

        Alternatively if you mean there is some global QEvent::LanguageChange event, can you catch that at the top level and visit all your widgets via QWidgetList QApplication::allWidgets() to do whatever you have to do to change their language?

        C 1 Reply Last reply
        0
        • VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by VRonin
          #3

          Macro time!

          #define MAKE_TRANSLATABLE(BaseClass) \
              protected: \
              void changeEvent(QEvent * event) override{ \
                  if (event->type() == QEvent::LanguageChange) \
                      ui->retranslateUi(this); \
                  BaseClass::changeEvent(event); \
              }
          #define MAKE_TRANSLATABLE_F(BaseClass, TranslateMethod) \
              protected: \
              void changeEvent(QEvent * event) override{ \
                  if (event->type() == QEvent::LanguageChange) \
                      TranslateMethod(); \
                  BaseClass::changeEvent(event); \
              }
          
          class TranslatableWidget : public QWidget{
              MAKE_TRANSLATABLE(QWidget)
          };
          
          class TranslatableCustomWidget : public QWidget{
              MAKE_TRANSLATABLE_F(QWidget,customRetranslateMethod)
          protected:
              void customRetranslateMethod();
          };
          

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          C 1 Reply Last reply
          2
          • JonBJ JonB

            @Christian-Woznik
            There may well be a better way (I don't use translation). But in general in Qt if you want to do something to every widget instead of hooking onto each one (e.g. changeEvent()) one implements bool QObject::eventFilter(QObject *watched, QEvent *event) or maybe bool QObject::event(QEvent *e). My understanding is you can do this on some top-level widget (window/dialog/main window/whatever) and it will see all events that are destined for descendent widgets.

            Alternatively if you mean there is some global QEvent::LanguageChange event, can you catch that at the top level and visit all your widgets via QWidgetList QApplication::allWidgets() to do whatever you have to do to change their language?

            C Offline
            C Offline
            Christian Woznik
            wrote on last edited by
            #4

            @JonB Unfortunately that does not help me. I need to call ui->translate(*QWidget) in each of the widgets. And of course the UI is only defined as private inside the individual widgets / windows.
            I would either have to set the UI elements to public, an idea I do not like at all, to then update it or I have to do the same with a virtual public function I would call during the iteration.

            JonBJ J.HilkJ 3 Replies Last reply
            0
            • C Christian Woznik

              @JonB Unfortunately that does not help me. I need to call ui->translate(*QWidget) in each of the widgets. And of course the UI is only defined as private inside the individual widgets / windows.
              I would either have to set the UI elements to public, an idea I do not like at all, to then update it or I have to do the same with a virtual public function I would call during the iteration.

              JonBJ Online
              JonBJ Online
              JonB
              wrote on last edited by
              #5

              @Christian-Woznik said in Dynamic retranslation without reimplementing the changeEvent in every window/widget:

              ui->translate(*QWidget) in each of the widgets

              If you say so. What does ui->translate() do that actually requires the ui instance/object to do its work?

              In any case, if @VRonin says to do it with a macro I'm sure he's right! Though how that helps you not have to do it (and subclass) against every different type of widget you use I don't see....?

              JonBJ 1 Reply Last reply
              0
              • C Christian Woznik

                @JonB Unfortunately that does not help me. I need to call ui->translate(*QWidget) in each of the widgets. And of course the UI is only defined as private inside the individual widgets / windows.
                I would either have to set the UI elements to public, an idea I do not like at all, to then update it or I have to do the same with a virtual public function I would call during the iteration.

                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by
                #6

                @Christian-Woznik actually, if all your widgets are in a parent child relation, than calling ui->retranslateUi(this); on your top parent widget should recursively retranslate all children as well.

                exception are of cause all strings you have set inside your code "manually". Those have to be called again


                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                C 1 Reply Last reply
                0
                • VRoninV VRonin

                  Macro time!

                  #define MAKE_TRANSLATABLE(BaseClass) \
                      protected: \
                      void changeEvent(QEvent * event) override{ \
                          if (event->type() == QEvent::LanguageChange) \
                              ui->retranslateUi(this); \
                          BaseClass::changeEvent(event); \
                      }
                  #define MAKE_TRANSLATABLE_F(BaseClass, TranslateMethod) \
                      protected: \
                      void changeEvent(QEvent * event) override{ \
                          if (event->type() == QEvent::LanguageChange) \
                              TranslateMethod(); \
                          BaseClass::changeEvent(event); \
                      }
                  
                  class TranslatableWidget : public QWidget{
                      MAKE_TRANSLATABLE(QWidget)
                  };
                  
                  class TranslatableCustomWidget : public QWidget{
                      MAKE_TRANSLATABLE_F(QWidget,customRetranslateMethod)
                  protected:
                      void customRetranslateMethod();
                  };
                  
                  C Offline
                  C Offline
                  Christian Woznik
                  wrote on last edited by
                  #7

                  @VRonin I guess that is an option to not always write it. I am just not sure how I feel about it yet as I am normally trying to avoid macros. I feel it makes it hard to maintain the code but I guess in this instance it is a valid usecase.

                  Thanks.

                  1 Reply Last reply
                  0
                  • J.HilkJ J.Hilk

                    @Christian-Woznik actually, if all your widgets are in a parent child relation, than calling ui->retranslateUi(this); on your top parent widget should recursively retranslate all children as well.

                    exception are of cause all strings you have set inside your code "manually". Those have to be called again

                    C Offline
                    C Offline
                    Christian Woznik
                    wrote on last edited by Christian Woznik
                    #8

                    @J-Hilk are you sure? I have my mainWindow containing a stackedWidget. I just took a look inside the generated ui_mainwindow.h but the retranslateUI function does not call the translate function for the individual pages so how would it call it recursively? I am not even sure how it would be possible.

                    The only thing the function does it call QCoreApplication::translate for all of the set texts.

                        void retranslateUi(QMainWindow *MainWindow)
                        {
                            MainWindow->setWindowTitle(QCoreApplication::translate("MainWindow", "abc1", nullptr));
                            lbMachineType->setText(QCoreApplication::translate("MainWindow", "abc2", nullptr));
                            lbManufacturer->setText(QCoreApplication::translate("MainWindow", "abc3", nullptr));
                            lbManufacturerGraphic->setText(QString());
                            pbLang->setText(QString());
                            lbPageNR->setText("1000");
                            pbLeft->setText(QString());
                            pbRight->setText(QString());
                            pbSettings->setText(QString());
                        } // retranslateUi
                    

                    @JonB
                    As you can see it needs to access all the ui elements individually to set the text. So it is unavoidable to have access to the ui instance of each widget.

                    J.HilkJ 1 Reply Last reply
                    0
                    • C Christian Woznik

                      @J-Hilk are you sure? I have my mainWindow containing a stackedWidget. I just took a look inside the generated ui_mainwindow.h but the retranslateUI function does not call the translate function for the individual pages so how would it call it recursively? I am not even sure how it would be possible.

                      The only thing the function does it call QCoreApplication::translate for all of the set texts.

                          void retranslateUi(QMainWindow *MainWindow)
                          {
                              MainWindow->setWindowTitle(QCoreApplication::translate("MainWindow", "abc1", nullptr));
                              lbMachineType->setText(QCoreApplication::translate("MainWindow", "abc2", nullptr));
                              lbManufacturer->setText(QCoreApplication::translate("MainWindow", "abc3", nullptr));
                              lbManufacturerGraphic->setText(QString());
                              pbLang->setText(QString());
                              lbPageNR->setText("1000");
                              pbLeft->setText(QString());
                              pbRight->setText(QString());
                              pbSettings->setText(QString());
                          } // retranslateUi
                      

                      @JonB
                      As you can see it needs to access all the ui elements individually to set the text. So it is unavoidable to have access to the ui instance of each widget.

                      J.HilkJ Offline
                      J.HilkJ Offline
                      J.Hilk
                      Moderators
                      wrote on last edited by
                      #9

                      @Christian-Woznik said in Dynamic retranslation without reimplementing the changeEvent in every window/widget:

                      are you sure?

                      No, I was going of on memory and it seems I was wrong :(


                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                      Q: What's that?
                      A: It's blue light.
                      Q: What does it do?
                      A: It turns blue.

                      1 Reply Last reply
                      0
                      • VRoninV Offline
                        VRoninV Offline
                        VRonin
                        wrote on last edited by
                        #10

                        The "base class method" also falls short if you are subclassing a different class e.g. QDialog vs QWidget

                        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                        ~Napoleon Bonaparte

                        On a crusade to banish setIndexWidget() from the holy land of Qt

                        C 1 Reply Last reply
                        0
                        • VRoninV VRonin

                          The "base class method" also falls short if you are subclassing a different class e.g. QDialog vs QWidget

                          C Offline
                          C Offline
                          Christian Woznik
                          wrote on last edited by
                          #11

                          @VRonin
                          Yeah I agree. It would require subclassing for each type. So QMainWindow, QWidget and QDialog in my situation. This is one of the reasons why I do not like it. I guess in the end the macro alternative is the best way.

                          1 Reply Last reply
                          0
                          • JonBJ JonB

                            @Christian-Woznik said in Dynamic retranslation without reimplementing the changeEvent in every window/widget:

                            ui->translate(*QWidget) in each of the widgets

                            If you say so. What does ui->translate() do that actually requires the ui instance/object to do its work?

                            In any case, if @VRonin says to do it with a macro I'm sure he's right! Though how that helps you not have to do it (and subclass) against every different type of widget you use I don't see....?

                            JonBJ Online
                            JonBJ Online
                            JonB
                            wrote on last edited by JonB
                            #12

                            @Christian-Woznik

                            @JonB said in Dynamic retranslation without reimplementing the changeEvent in every window/widget:

                            If you say so. What does ui->translate() do that actually requires the ui instance/object to do its work?

                            ?

                            I find it hard to believe/understand what you need to do which cannot be done by visiting each widget individually via QWidgetList QApplication::allWidgets(), without needing ui/private variables, like I said.

                            C 1 Reply Last reply
                            0
                            • JonBJ JonB

                              @Christian-Woznik

                              @JonB said in Dynamic retranslation without reimplementing the changeEvent in every window/widget:

                              If you say so. What does ui->translate() do that actually requires the ui instance/object to do its work?

                              ?

                              I find it hard to believe/understand what you need to do which cannot be done by visiting each widget individually via QWidgetList QApplication::allWidgets(), without needing ui/private variables, like I said.

                              C Offline
                              C Offline
                              Christian Woznik
                              wrote on last edited by
                              #13

                              @JonB Well then tell me how. The UI object is private inside the individual widget / window class. There is no public function by default that I could use to invoke the retranslate. I mean QT's documentation says you have to do it via the event.

                              I am also not happy with that solution but using macros does the trick and avoids writing the same code dozents of times. If you know a better alternative I would gladly take it.

                              1 Reply Last reply
                              0
                              • C Christian Woznik

                                @JonB Unfortunately that does not help me. I need to call ui->translate(*QWidget) in each of the widgets. And of course the UI is only defined as private inside the individual widgets / windows.
                                I would either have to set the UI elements to public, an idea I do not like at all, to then update it or I have to do the same with a virtual public function I would call during the iteration.

                                JonBJ Online
                                JonBJ Online
                                JonB
                                wrote on last edited by JonB
                                #14

                                @Christian-Woznik said in Dynamic retranslation without reimplementing the changeEvent in every window/widget:

                                @JonB Unfortunately that does not help me. I need to call ui->translate(*QWidget) in each of the widgets

                                That's what you wrote. Turns out there is no such ui->translate(), and you meant ui->retranslateUi(). I am not a mind reader and didn't know that.

                                Now that I look at that implementation from a designer-generated ui_....h file I can see that it not only visits each widget --- which could be done via QApplication::allWidgets() instead without needing to access any ui private variable --- but it also holds the the original-language text for each widget which it calls QApplication::translate() on. It's not how I would have implemented it :) though I can see it saves space and is convenient if you're not doing any translating. But it stops us from doing a "global retranslate all widgets to new language", which seems a shame.

                                Given that I can now see why ui->retranslateUi() must actually be called again when language changes. And that must be done for each top-level/designed widget-type you have. And you have to define a separate class like TranslatableWidget for every one of them and use that instead of the class you would have had in Designer, such as via the macros and classes in the example above. Nasty :(

                                Only you/ @VRonin know whether this might be achieved via a template in C++ rather than a macro, if you prefer that.

                                If you want to avoid the need to subclass to use @VRonin's approach --- which is what really bothers me --- you could presumably have each of your top-level/designed UI widgets define a slot which calls its private ui->retranslateUi(). And then have a single application-wide capture of QEvent::LanguageChange which emits a signal that you connect to each of these slots when you call ui->setupUi() in each top-level/designed widget. That is probably what I would do, as I don't want to have to sub-class each one just to make it translatable. @VRonin is welcome to comment/criticise if I have said anything erroneous.

                                C VRoninV 2 Replies Last reply
                                0
                                • JonBJ JonB

                                  @Christian-Woznik said in Dynamic retranslation without reimplementing the changeEvent in every window/widget:

                                  @JonB Unfortunately that does not help me. I need to call ui->translate(*QWidget) in each of the widgets

                                  That's what you wrote. Turns out there is no such ui->translate(), and you meant ui->retranslateUi(). I am not a mind reader and didn't know that.

                                  Now that I look at that implementation from a designer-generated ui_....h file I can see that it not only visits each widget --- which could be done via QApplication::allWidgets() instead without needing to access any ui private variable --- but it also holds the the original-language text for each widget which it calls QApplication::translate() on. It's not how I would have implemented it :) though I can see it saves space and is convenient if you're not doing any translating. But it stops us from doing a "global retranslate all widgets to new language", which seems a shame.

                                  Given that I can now see why ui->retranslateUi() must actually be called again when language changes. And that must be done for each top-level/designed widget-type you have. And you have to define a separate class like TranslatableWidget for every one of them and use that instead of the class you would have had in Designer, such as via the macros and classes in the example above. Nasty :(

                                  Only you/ @VRonin know whether this might be achieved via a template in C++ rather than a macro, if you prefer that.

                                  If you want to avoid the need to subclass to use @VRonin's approach --- which is what really bothers me --- you could presumably have each of your top-level/designed UI widgets define a slot which calls its private ui->retranslateUi(). And then have a single application-wide capture of QEvent::LanguageChange which emits a signal that you connect to each of these slots when you call ui->setupUi() in each top-level/designed widget. That is probably what I would do, as I don't want to have to sub-class each one just to make it translatable. @VRonin is welcome to comment/criticise if I have said anything erroneous.

                                  C Offline
                                  C Offline
                                  Christian Woznik
                                  wrote on last edited by
                                  #15

                                  @JonB Well sorry for the confusion. I just wrote it wrongly there. But in my original post its correct as it was actual testcode and it compiled.

                                  As for the global capture. I do not see where the subclassing is bad? I anyways have to do it for each window or custom dialog I want to show. I mean that is exactly what QT is doing when you add a new window, it creates a subclass from the QMainWindow, QWidget or QDialog class. And there I can just add the macro, it works fine. It is just that the usage of macros at my workplace is not really welcome but

                                  I also would not know how to do it your way without subclassing as well? Or am I missing something there? Even the basic mainWindow is a subclass of QMainWindow.

                                  1 Reply Last reply
                                  0
                                  • JonBJ JonB

                                    @Christian-Woznik said in Dynamic retranslation without reimplementing the changeEvent in every window/widget:

                                    @JonB Unfortunately that does not help me. I need to call ui->translate(*QWidget) in each of the widgets

                                    That's what you wrote. Turns out there is no such ui->translate(), and you meant ui->retranslateUi(). I am not a mind reader and didn't know that.

                                    Now that I look at that implementation from a designer-generated ui_....h file I can see that it not only visits each widget --- which could be done via QApplication::allWidgets() instead without needing to access any ui private variable --- but it also holds the the original-language text for each widget which it calls QApplication::translate() on. It's not how I would have implemented it :) though I can see it saves space and is convenient if you're not doing any translating. But it stops us from doing a "global retranslate all widgets to new language", which seems a shame.

                                    Given that I can now see why ui->retranslateUi() must actually be called again when language changes. And that must be done for each top-level/designed widget-type you have. And you have to define a separate class like TranslatableWidget for every one of them and use that instead of the class you would have had in Designer, such as via the macros and classes in the example above. Nasty :(

                                    Only you/ @VRonin know whether this might be achieved via a template in C++ rather than a macro, if you prefer that.

                                    If you want to avoid the need to subclass to use @VRonin's approach --- which is what really bothers me --- you could presumably have each of your top-level/designed UI widgets define a slot which calls its private ui->retranslateUi(). And then have a single application-wide capture of QEvent::LanguageChange which emits a signal that you connect to each of these slots when you call ui->setupUi() in each top-level/designed widget. That is probably what I would do, as I don't want to have to sub-class each one just to make it translatable. @VRonin is welcome to comment/criticise if I have said anything erroneous.

                                    VRoninV Offline
                                    VRoninV Offline
                                    VRonin
                                    wrote on last edited by
                                    #16

                                    @JonB said in Dynamic retranslation without reimplementing the changeEvent in every window/widget:

                                    Only you/ @VRonin know whether this might be achieved via a template in C++ rather than a macro, if you prefer that.

                                    You can use templates:

                                    template <class T>
                                    class TranstatableW : public T{
                                    static_assert(std::is_base_of<QWidget,T>::value,"Template argument must be a QWidget");
                                    public:
                                    using T::T;
                                    protected:
                                        void changeEvent(QEvent * event) override{
                                            if (event->type() == QEvent::LanguageChange)
                                                retranslate();
                                            BaseClass::changeEvent(event);
                                        }
                                    virtual void retranslate() = 0;
                                    };
                                    

                                    now all you need is to replace class MyWidget : public QWidget with class MyWidget : public TranstatableW<QWidget> but you'll always have to provide an overload for retranslate so probably more code

                                    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                    ~Napoleon Bonaparte

                                    On a crusade to banish setIndexWidget() from the holy land of Qt

                                    1 Reply Last reply
                                    2

                                    • Login

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