Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. PyQt Multi Language problem
Forum Updated to NodeBB v4.3 + New Features

PyQt Multi Language problem

Scheduled Pinned Locked Moved Solved Qt for Python
14 Posts 4 Posters 2.7k Views 2 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.
  • H Offline
    H Offline
    Hai Anh Luu
    wrote on last edited by
    #1

    I used Qt Linguist to translate languages for my application, it works fine. But I have a problem that when I click change language, widgets all change language, only QDialog is not updating. I used tr(" ") for all the strings in the QDialog, and translated them to .ts and .qm files but it still doesn't work. Can anyone help me?

    1 Reply Last reply
    0
    • SGaistS SGaist moved this topic from General and Desktop on
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      How are you creating that dialog ?
      How do you handle the language in it ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      H 1 Reply Last reply
      0
      • SGaistS SGaist

        Hi and welcome to devnet,

        How are you creating that dialog ?
        How do you handle the language in it ?

        H Offline
        H Offline
        Hai Anh Luu
        wrote on last edited by
        #3

        @SGaist I am not using default Qt Dialogs. I am using custom dialogs with extend the QDialog class and having a ui file. In Mainwindow, I have QTabWidget. In each screen, I have one or two button, when the button is pressed, it will display a dialog. For example, in screen 1, I have 2 buttons, when I press button 1, the language of the application will change, but when I press button 2 to display the Dialog, the language of the Dialog does not update. I initialize the Dialog at clicked.connect().
        My code:
        def showDialog(self):
        self.dialog = DialogInMap()
        self.dialog.setObjectName("DialogInMap")
        self.dialog.show()

        And my dialog:

        class DialogInMap(QDialog):
        def init(self):
        super().init()
        self.setObjectName("DialogInMap")
        self.load_ui()

        def load_ui(self):
            # create label
            self.mylabel = QLabel(self.tr("Dialog in Map"))
            # center
            self.mylabel.setAlignment(Qt.AlignCenter)
        
            self.label_2 = QLabel(self.tr("Hello in Map"))
        
            # create layout
            self.layout = QVBoxLayout()
            self.layout.setAlignment(Qt.AlignTop)
        
            self.layout.addWidget(self.mylabel)
            self.layout.addWidget(self.label_2)
            self.setLayout(self.layout)
        
        S 1 Reply Last reply
        0
        • H Hai Anh Luu

          @SGaist I am not using default Qt Dialogs. I am using custom dialogs with extend the QDialog class and having a ui file. In Mainwindow, I have QTabWidget. In each screen, I have one or two button, when the button is pressed, it will display a dialog. For example, in screen 1, I have 2 buttons, when I press button 1, the language of the application will change, but when I press button 2 to display the Dialog, the language of the Dialog does not update. I initialize the Dialog at clicked.connect().
          My code:
          def showDialog(self):
          self.dialog = DialogInMap()
          self.dialog.setObjectName("DialogInMap")
          self.dialog.show()

          And my dialog:

          class DialogInMap(QDialog):
          def init(self):
          super().init()
          self.setObjectName("DialogInMap")
          self.load_ui()

          def load_ui(self):
              # create label
              self.mylabel = QLabel(self.tr("Dialog in Map"))
              # center
              self.mylabel.setAlignment(Qt.AlignCenter)
          
              self.label_2 = QLabel(self.tr("Hello in Map"))
          
              # create layout
              self.layout = QVBoxLayout()
              self.layout.setAlignment(Qt.AlignTop)
          
              self.layout.addWidget(self.mylabel)
              self.layout.addWidget(self.label_2)
              self.setLayout(self.layout)
          
          S Offline
          S Offline
          StarterKit
          wrote on last edited by
          #4

          Hi @Hai-Anh-Luu
          I had similar problem some time ago. If you look into files generated by Qt Designer you will se that it contains retraslateUi() methods.
          There is no magic behind - this method is called to set right text strings for currently choosen language. And it is called as part of your application start-up routine.
          So if you want to change language on the fly - you need to call retranslateUi() for every dialog/window you have. How to do it depends on you application. For mine I decided that the simplest way is to restart application after UI language change.

          JonBJ 1 Reply Last reply
          0
          • S StarterKit

            Hi @Hai-Anh-Luu
            I had similar problem some time ago. If you look into files generated by Qt Designer you will se that it contains retraslateUi() methods.
            There is no magic behind - this method is called to set right text strings for currently choosen language. And it is called as part of your application start-up routine.
            So if you want to change language on the fly - you need to call retranslateUi() for every dialog/window you have. How to do it depends on you application. For mine I decided that the simplest way is to restart application after UI language change.

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

            @StarterKit
            I would have answered that way, but not given that OP claims

            when I click change language, widgets all change language, only QDialog is not updating.

            If it were a matter of all widgets need re-translating, how would the OP report that other widgets change language but only a QDialog does not?

            I still suspect retranslation is necessary, but cannot explain the OP's observation in this light.

            S 1 Reply Last reply
            0
            • JonBJ JonB

              @StarterKit
              I would have answered that way, but not given that OP claims

              when I click change language, widgets all change language, only QDialog is not updating.

              If it were a matter of all widgets need re-translating, how would the OP report that other widgets change language but only a QDialog does not?

              I still suspect retranslation is necessary, but cannot explain the OP's observation in this light.

              S Offline
              S Offline
              StarterKit
              wrote on last edited by
              #6

              @JonB, topic starter haven't mentioned anything about retranslateUi() and how (s)he calls it. So, I have a reason to suspect that it was called for one window but not for another. Am I right? I don't know. But I see reasons to suspect this kind of behavior.

              SGaistS 1 Reply Last reply
              1
              • S StarterKit

                @JonB, topic starter haven't mentioned anything about retranslateUi() and how (s)he calls it. So, I have a reason to suspect that it was called for one window but not for another. Am I right? I don't know. But I see reasons to suspect this kind of behavior.

                SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @StarterKit retranslateUi is a method generated not a standard QWidget method however, you are getting in the correct direction.

                @Hai-Anh-Luu what you need to do is to implement your own retranslateUi method and call it from both the __init__ function (or load_ui function) and from the changeEvent function when the QEvent.LanguageEvent happens. Set all the texts of your various dialog widgets in retranslateUi.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                H 1 Reply Last reply
                2
                • SGaistS SGaist

                  @StarterKit retranslateUi is a method generated not a standard QWidget method however, you are getting in the correct direction.

                  @Hai-Anh-Luu what you need to do is to implement your own retranslateUi method and call it from both the __init__ function (or load_ui function) and from the changeEvent function when the QEvent.LanguageEvent happens. Set all the texts of your various dialog widgets in retranslateUi.

                  H Offline
                  H Offline
                  Hai Anh Luu
                  wrote on last edited by
                  #8

                  @SGaist Thank for your answer. I wrote the retranslateUi() function and put it in the load_ui() function after initializing the QLabels. But without any change, my QDialog is still not updating. This is my retranslateUi() function:

                  def retranslateUi(self):
                      self.mylabel.setText(QCoreApplication.translate("DialogInMap", u"Dialog in Map", None))
                      self.label_2.setText(QCoreApplication.translate("DialogInMap", u"Hello in Map", None))
                  

                  And this is my .ts file in vi_VN language, in en_US.ts, I do not translate use translation type="unfinished"></translation> , so I will not show it here:

                  <context>
                  <name>DialogInMap</name>
                  <message>
                  <location filename="../presentation/map_screen/dialog_map.py" line="12"/>
                  <source>Dialog in Map</source>
                  <translation type="unfinished">Hộp thoại ở Map</translation>
                  </message>
                  <message>
                  <location filename="../presentation/map_screen/dialog_map.py" line="16"/>
                  <source>Hello in Map</source>
                  <translation type="unfinished">Xin chào ở Map</translation>
                  </message>
                  </context>

                  @StarterKit Thank for your answer, but I just want to update language without restart application.

                  JonBJ SGaistS 2 Replies Last reply
                  0
                  • H Hai Anh Luu

                    @SGaist Thank for your answer. I wrote the retranslateUi() function and put it in the load_ui() function after initializing the QLabels. But without any change, my QDialog is still not updating. This is my retranslateUi() function:

                    def retranslateUi(self):
                        self.mylabel.setText(QCoreApplication.translate("DialogInMap", u"Dialog in Map", None))
                        self.label_2.setText(QCoreApplication.translate("DialogInMap", u"Hello in Map", None))
                    

                    And this is my .ts file in vi_VN language, in en_US.ts, I do not translate use translation type="unfinished"></translation> , so I will not show it here:

                    <context>
                    <name>DialogInMap</name>
                    <message>
                    <location filename="../presentation/map_screen/dialog_map.py" line="12"/>
                    <source>Dialog in Map</source>
                    <translation type="unfinished">Hộp thoại ở Map</translation>
                    </message>
                    <message>
                    <location filename="../presentation/map_screen/dialog_map.py" line="16"/>
                    <source>Hello in Map</source>
                    <translation type="unfinished">Xin chào ở Map</translation>
                    </message>
                    </context>

                    @StarterKit Thank for your answer, but I just want to update language without restart application.

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by
                    #9

                    @Hai-Anh-Luu
                    I think you should do some simple debugging (print() statements) which will help you/us identify where the problem lies:

                    • Show what the currently installed/active translation is immediately before the translate() statements.
                    • Just output print(QCoreApplication.translate("DialogInMap", u"Dialog in Map", None)), now we don't have to worry about setting widget texts.
                    • Copy that line to immediately after wherever you change the translation language. Now we don't have to worry about being in dialog code.
                    • Create a plain QDialog, not sub-classed. Test that for translation.
                    1 Reply Last reply
                    0
                    • H Hai Anh Luu

                      @SGaist Thank for your answer. I wrote the retranslateUi() function and put it in the load_ui() function after initializing the QLabels. But without any change, my QDialog is still not updating. This is my retranslateUi() function:

                      def retranslateUi(self):
                          self.mylabel.setText(QCoreApplication.translate("DialogInMap", u"Dialog in Map", None))
                          self.label_2.setText(QCoreApplication.translate("DialogInMap", u"Hello in Map", None))
                      

                      And this is my .ts file in vi_VN language, in en_US.ts, I do not translate use translation type="unfinished"></translation> , so I will not show it here:

                      <context>
                      <name>DialogInMap</name>
                      <message>
                      <location filename="../presentation/map_screen/dialog_map.py" line="12"/>
                      <source>Dialog in Map</source>
                      <translation type="unfinished">Hộp thoại ở Map</translation>
                      </message>
                      <message>
                      <location filename="../presentation/map_screen/dialog_map.py" line="16"/>
                      <source>Hello in Map</source>
                      <translation type="unfinished">Xin chào ở Map</translation>
                      </message>
                      </context>

                      @StarterKit Thank for your answer, but I just want to update language without restart application.

                      SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      @Hai-Anh-Luu from what you wrote, you did not implement one of the most important thing: the changeEvent method. That's the one you need for dynamic translation to happen.

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      S 1 Reply Last reply
                      1
                      • SGaistS SGaist

                        @Hai-Anh-Luu from what you wrote, you did not implement one of the most important thing: the changeEvent method. That's the one you need for dynamic translation to happen.

                        S Offline
                        S Offline
                        StarterKit
                        wrote on last edited by
                        #11

                        Hi @SGaist
                        Thanks for mentioning QEvent.LanguageEvent - I overlooked it when I studied my problem.
                        My biggest pain was creation of retranalateUi() methods manually. There were too many stupid manual work so I decided that language change isn't an often thing and user may tolerate application restart that will handle all widgets automatically.

                        But as we have all this discussion - do you know any way or have any idea of how to automate retranslateUi() creation for custom dialogs? uic obviosly does it so I'm curios is there any better way rather then list all widgets by hand and keep them up to date...

                        SGaistS 1 Reply Last reply
                        0
                        • S StarterKit

                          Hi @SGaist
                          Thanks for mentioning QEvent.LanguageEvent - I overlooked it when I studied my problem.
                          My biggest pain was creation of retranalateUi() methods manually. There were too many stupid manual work so I decided that language change isn't an often thing and user may tolerate application restart that will handle all widgets automatically.

                          But as we have all this discussion - do you know any way or have any idea of how to automate retranslateUi() creation for custom dialogs? uic obviosly does it so I'm curios is there any better way rather then list all widgets by hand and keep them up to date...

                          SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          @StarterKit how many widgets do you have in that dialog ?

                          The only thing you need to do for getting translated widgets is to move all the setText or equivalent calls from the constructor to the "retranslateUi" method.

                          Interested in AI ? www.idiap.ch
                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                          S 1 Reply Last reply
                          1
                          • SGaistS SGaist

                            @StarterKit how many widgets do you have in that dialog ?

                            The only thing you need to do for getting translated widgets is to move all the setText or equivalent calls from the constructor to the "retranslateUi" method.

                            S Offline
                            S Offline
                            StarterKit
                            wrote on last edited by
                            #13

                            @SGaist, Thanks!
                            I see your point - if I have .setText() anyway in a constructor I may move it to retranslateUi() and just make a single call. I haven't thought this way. I'll refactor.

                            H 1 Reply Last reply
                            0
                            • S StarterKit

                              @SGaist, Thanks!
                              I see your point - if I have .setText() anyway in a constructor I may move it to retranslateUi() and just make a single call. I haven't thought this way. I'll refactor.

                              H Offline
                              H Offline
                              Hai Anh Luu
                              wrote on last edited by Hai Anh Luu
                              #14

                              I finally found the solution. Do not need retranslateUi() in QDialog because if the translations exist, and the translation is loaded correctly, when create new Dialog (show() or exec() action), it will also show the appropriate translated text.

                              My error was loading wrong QTranslator in QApplication. In QMainWindow, this is my correct code:

                              translator variable must use in both if name function and in body of QMainWindow. Earlier I made the mistake of instantiating a new QTranslator in the body of the QMainWindow (change_language() fuction) and using it to load the new language, so it was out of sync with the original QTranslator in the name function.

                                  def change_language(self):
                                      current_language = None
                                      if LanguageQSettings().get_current_language() == Style.Language.vie:
                                          # Set tieng Anh o day
                                          current_language = Style.Language.en
                                      else:
                                          # Set tieng Viet o day
                                          current_language = Style.Language.vie
                              
                                      translator.load(current_language)
                                      app.installTranslator(translator)
                                      self.retranslateUi()
                                      LanguageQSettings().set_current_language(current_language)
                              
                                  def retranslateUi(self):
                                      self.home_screen.retranslate_Ui()
                                      if not self.login_screen.deleteLater:
                                          self.login_screen.retranslateUi_login()
                                      self.update()
                              
                              
                              if __name__ == "__main__":
                                  app = QApplication(sys.argv)
                                  translator = QTranslator()
                                  translator.load(LanguageQSettings().get_current_language())
                                  app.installTranslator(translator)
                              
                                  app.setWindowIcon(QIcon(Style.Image.icon128))
                                  app.setApplicationName(Style.Text.app_name)
                                  widget = MainWindow()
                                  widget.show()
                                  sys.exit(app.exec())```
                              1 Reply Last reply
                              0
                              • H Hai Anh Luu has marked this topic as solved on

                              • Login

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