Home > Mobile >  Actively change language of a GUI in PyQt5
Actively change language of a GUI in PyQt5

Time:12-14

I'm working on multithread PyQt5 application. Now I want to convert it to append multi language support, using two puss buttons, which might dynamically change bunch of labels (images and texts).

I wrote a simpler code below, merely to demonstrate my problem. I already know that I should add setText() in btn1_onClicked() and btn2_onClicked() functions to make it work though. But I'm barely looking for any alternative way to do it without changing onClicked functions. Because in my main script, texts are sent via pyqtsignal in an Infinite while loop (implemented in a worker thread).

Hence, I really appreciate if one can help me do it without changing btn1_onClicked() and btn2_onClicked() functions.

Thanks

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel

hello_en = 'Hello'
hello_fr = 'bonjour'

class MultiButtons(QWidget):

    def __init__(self):
        # Call parent constructor
        super().__init__()
        self.lang = 'en'

        self.btn1 = QPushButton('English', self)
        self.btn1.setGeometry(130, 70, 60, 40)
        self.btn1.clicked.connect(self.btn1_onClicked)

        self.btn2 = QPushButton('Francias', self)
        self.btn2.setGeometry(200, 70, 60, 40)
        self.btn2.clicked.connect(self.btn2_onClicked)

        self.msgLabel = QLabel('', self)
        self.msgLabel.setGeometry(130, 120, 300, 80)

        self.setWindowTitle('Use of multiple PushButtons')
        self.setGeometry(10, 10, 400, 200)
        self.msgLabel.setText(F"{hello_en if (self.lang == 'en') else hello_fr}")

        self.move(850, 300)
        self.show()

    def btn1_onClicked(self):
        self.lang = 'en'

    def btn2_onClicked(self):
        self.lang = 'fr'

app = QApplication(sys.argv)
button = MultiButtons()
app.exec()

CodePudding user response:

I have found something, but I'm not sure if it is a standard way.

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel

hello_en = 'Hello'
hello = 'bonjour'

def get_variable_name(variable):
    globals_dict = globals()
    return [var_name for var_name in globals_dict if globals_dict[var_name] is variable]

class MultiButtons(QWidget):

    def __init__(self):
        # Call parent constructor
        super().__init__()
        self.lang = 'en'

        self.btn1 = QPushButton('English', self)
        self.btn1.setGeometry(130, 70, 60, 40)
        self.btn1.clicked.connect(self.btn1_onClicked)
        

        self.btn2 = QPushButton('Francias', self)
        self.btn2.setGeometry(200, 70, 60, 40)
        self.btn2.clicked.connect(self.btn2_onClicked)

        self.msgLabel = QLabel('', self)
        self.msgLabel.setGeometry(130, 120, 300, 80)

        self.setWindowTitle('Use of multiple PushButtons')
        self.setGeometry(10, 10, 500, 200)
        self.SET_Text(hello)

        self.btn1.clicked.connect(lambda : self.SET_Text(hello))
        self.btn2.clicked.connect(lambda : self.SET_Text(hello))
        

        self.move(850, 300)
        self.show()

    def btn1_onClicked(self):
        self.lang = 'en'

    def btn2_onClicked(self):
        self.lang = 'fa'

    def SET_Text(self,s):
        if self.lang == 'fa':
            txt = globals()[get_variable_name(s)[0]]
        elif self.lang == 'en':
            txt = globals()[get_variable_name(s)[0] '_en']
        self.msgLabel.setText(txt)
        
    
    

app = QApplication(sys.argv)
button = MultiButtons()
app.exec()

CodePudding user response:

If you need to use buttons and don't want to change your onClicked functions you could connect another function after your calls to your onClicked functions, like below:

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel

hello_en = 'Hello'
hello_fr = 'bonjour'

class MultiButtons(QWidget):

    def __init__(self):
        # Call parent constructor
        super().__init__()
        self.lang = 'en'

        self.btn1 = QPushButton('English', self)
        self.btn1.setGeometry(130, 70, 60, 40)
        self.btn1.clicked.connect(self.btn1_onClicked)
        self.btn1.clicked.connect(self.set_language_texts)

        self.btn2 = QPushButton('Francias', self)
        self.btn2.setGeometry(200, 70, 60, 40)
        self.btn2.clicked.connect(self.btn2_onClicked)
        self.btn2.clicked.connect(self.set_language_texts)

        self.msgLabel = QLabel('', self)
        self.msgLabel.setGeometry(130, 120, 300, 80)

        self.setWindowTitle('Use of multiple PushButtons')
        self.setGeometry(10, 10, 400, 200)
        self.msgLabel.setText(F"{hello_en if (self.lang == 'en') else hello_fr}")

        self.move(850, 300)
        self.show()

    def btn1_onClicked(self):
        self.lang = 'en'

    def btn2_onClicked(self):
        self.lang = 'fr'

    def set_language_texts(self):
        self.msgLabel.setText(F"{hello_en if (self.lang == 'en') else hello_fr}")
            

app = QApplication(sys.argv)
button = MultiButtons()
app.exec()

If you wanted to add quite a few languages, i'd recommend adding a comboxbox to switch and then have a bunch of lists stored (or set the lists from another class if strings aren't being stored locally) with the different label versions/images you would want to change. Something like this:

from PyQt5.QtWidgets import * 
import sys
class ComboBoxLanguages(QWidget):
    languageStrings = ["English", "French", "German", "Quenya"]
    label1Strings = ["Hello", "Bonjour", "Hallo", "Namárië"]
    label2Strings = ["Farewell", "Bon Voyage", "Auf Wiedersehen", "Navaer"]
    
    def __init__(self):
        super().__init__()
        self.lang = self.languageStrings[0]

        self.combobox1 = QComboBox(self)
        self.combobox1.setGeometry(130, 70, 60, 40)
        [self.combobox1.addItem(lang) for lang in self.languageStrings]
        self.combobox1.currentTextChanged.connect(self.on_combobox_changed)
        
        self.msgLabel = QLabel(self.label1Strings[0], self)
        self.msgLabel.setGeometry(130, 120, 300, 80)
        
        self.msg2Label = QLabel(self.label2Strings[0], self)
        self.msg2Label.setGeometry(230, 120, 300, 80)

        self.setWindowTitle('Combobox Language Example')
        self.setGeometry(10, 10, 400, 200)
       
        self.move(850, 300)
        self.show()

    def on_combobox_changed(self, value):
        self.lang = value
        languageIndex = self.languageStrings.index(value)
        self.msgLabel.setText(self.label1Strings[languageIndex])
        self.msg2Label.setText(self.label2Strings[languageIndex])
            
app = QApplication(sys.argv)
button = ComboBoxLanguages()
app.exec()
  • Related