In order to internationalize the text displayed in all of our GUI widgets, we have to move all hardcoded strings into a separate Python module, and this is what we'll do next.
Previously, strings of words that our GUI displayed were scattered all over our Python code.
Here is what our GUI looked like without I18N:
GUI_Refactored.py
Every single string of every widget, including the title of our GUI, the tab control names, and so on, were all hardcoded and intermixed with the code that creates the GUI.
The following is an excerpt of what our code looks like:
WIDGET_LABEL = ' Widgets Frame '
class OOP():
def __init__(self):
self.win = tk.Tk() # Create instance
self.win.title("Python GUI") # Add a title
# Radiobutton callback function
def radCall(self):
radSel=self.radVar.get()
if radSel == 0: self.monty2.configure(text='Blue')
elif radSel == 1: self.monty2.configure(text='Gold')
elif radSel == 2: self.monty2.configure(text='Red')
The following is the code for the english internationalized strings:
classI18N():
'''Internationalization'''
def __init__(self, language):
if language == 'en': self.resourceLanguageEnglish()
elif language == 'de': self.resourceLanguageGerman()
else: raiseNotImplementedError('Unsupported language.')
def resourceLanguageEnglish(self):
self.title = "Python Graphical User Interface"
self.file = "File"
self.new = "New"
self.exit = "Exit"
self.help = "Help"
self.about = "About"
self.WIDGET_LABEL = ' Widgets Frame '
self.disabled = "Disabled"
self.unChecked = "UnChecked"
self.toggle = "Toggle"
# Radiobutton list
self.colors = ["Blue", "Gold", "Red"]
self.colorsIn = ["in Blue", "in Gold", "in Red"]
self.labelsFrame = ' Labels within a Frame '
self.chooseNumber = "Choose a number:"
self.label2 = "Label 2"
self.mgrFiles = ' Manage Files '
self.browseTo = "Browse to File..."
self.copyTo = "Copy File To : "
In our Python GUI module, all previously hardcoded strings are now replaced by an instance of our new I18N class, which resides in the LanguageResources.py module.
Here is an example from our refactored GUI.py module:
from Ch08_Code.LanguageResources import I18N
class OOP():
def __init__(self):
self.win = tk.Tk() # Create instance
self.i18n = I18N('de') # Select language
self.win.title(self.i18n.title) # Add a title
# Radiobutton callback function
def radCall(self):
radSel = self.radVar.get()
if radSel == 0: self.widgetFrame.configure(text=
self.i18n.WIDGET_LABEL + self.i18n.colorsIn[0])
elif radSel == 1: self.widgetFrame.configure(text=
self.i18n.WIDGET_LABEL + self.i18n.colorsIn[1])
elif radSel == 2: self.widgetFrame.configure(text=
self.i18n.WIDGET_LABEL + self.i18n.colorsIn[2])
Note how all of the previously hardcoded English strings have been replaced by calls to the instance of our new I18N class. An example is self.win.title(self.i18n.title).
What this gives us is the ability to internationalize our GUI. We simply have to use the same variable names and combine them by passing in a parameter to select the language we wish to display.
We could change languages on the fly as part of the GUI as well, or we could read the local PC settings and decide which language our GUI text should display according to those settings.
We can now implement the translation to German by simply filling in the variable names with the corresponding words:
class I18N():
'''Internationalization'''
def __init__(self, language):
if language == 'en': self.resourceLanguageEnglish()
elif language == 'de': self.resourceLanguageGerman()
else: raise NotImplementedError('Unsupported language.')
def resourceLanguageGerman(self):
self.file = "Datei"
self.new = "Neu"
self.exit = "Schliessen"
self.help = "Hilfe"
self.about = "Ueber"
self.WIDGET_LABEL = ' Widgets Rahmen '
self.disabled = "Deaktiviert"
self.unChecked = "Nicht Markiert"
self.toggle = "Markieren"
# Radiobutton list
self.colors = ["Blau", "Gold", "Rot"]
self.colorsIn = ["in Blau", "in Gold", "in Rot"]
self.labelsFrame = ' Etiketten im Rahmen '
self.chooseNumber = "Waehle eine Nummer:"
self.label2 = "Etikette 2"
self.mgrFiles = ' Dateien Organisieren '
self.browseTo = "Waehle eine Datei... "
self.copyTo = "Kopiere Datei zu : "
In our GUI code, we can now change the entire GUI display language in one line of Python code:
classOOP():
def __init__(self):
self.win = tk.Tk() # Create instance
self.i18n = I18N('de') # Pass in language
Running the preceding code creates the following internationalized GUI:
GUI.py