Internationalization - i18n (Phoenix)

Keywords : i18n, Internationalization, Language.


Introduction

img_introduction_i18n.png


Demonstrating :

Tested py3.x, wx4.x and Win10.

Are you ready to use some samples ? ;)

Test, modify, correct, complete, improve and share your discoveries ! (!)


First example

img_sample_one.png

   1 # sample_one.py
   2 
   3 import os
   4 import wx
   5 import wx.adv
   6 
   7 # class MyFrame
   8 # class MyApp
   9 
  10 _ = wx.GetTranslation
  11 
  12 #---------------------------------------------------------------------------
  13 
  14 class MyFrame(wx.Frame):
  15     def __init__(self):
  16         wx.Frame.__init__(self, None, title=wx.GetApp().GetAppName())
  17         self.SetIcon(wx.Icon('icons/wxwin.ico'))
  18 
  19         self._createControls()
  20 
  21         self._connectControls()
  22 
  23     def _createControls(self):
  24         # A Statusbar in the bottom of the window
  25         self.CreateStatusBar(1)
  26         sMsg = 'wxPython ' + wx.version()
  27         self.SetStatusText(sMsg)
  28 
  29         # Menu bar
  30         menubar = wx.MenuBar()
  31         # File menu
  32         filemenu = wx.Menu()
  33         filemenu.Append(wx.ID_EXIT)
  34         menubar.Append(filemenu, wx.GetStockLabel(wx.ID_FILE))
  35         # Help menu
  36         helpmenu = wx.Menu()
  37         helpmenu.Append(wx.ID_ABOUT)
  38         menubar.Append(helpmenu, wx.GetStockLabel(wx.ID_HELP))
  39 
  40         self.SetMenuBar(menubar)
  41 
  42         # Add a panel to the frame (needed under Windows to have a nice background)
  43         pnl = wx.Panel(self, wx.ID_ANY)
  44 
  45         szrMain = wx.BoxSizer(wx.VERTICAL)
  46         szrMain.AddStretchSpacer(1)
  47         label = wx.StaticText(pnl, wx.ID_STATIC, _("Welcome from wxWidgets"))
  48         fnt = label.GetFont().MakeLarger().MakeLarger()
  49         label.SetFont(fnt)
  50         szrMain.Add(label, 0, wx.ALL|wx.ALIGN_CENTER, 10)
  51         szrMain.AddStretchSpacer(1)
  52         pnl.SetSizer(szrMain)
  53 
  54     def _connectControls(self):
  55         self.Bind(wx.EVT_MENU, self.onMenuExitClicked, id=wx.ID_EXIT)
  56         self.Bind(wx.EVT_MENU, self.onMenuAboutClicked, id=wx.ID_ABOUT)
  57 
  58     def onMenuExitClicked(self, evt):
  59         self.Close()
  60 
  61     def onMenuAboutClicked(self, evt):
  62         info = wx.adv.AboutDialogInfo()
  63         info.SetName('Internat')
  64         info.SetVersion('(v1.0.0)')
  65         info.SetDescription(_('wxWidgets I18N sample'))
  66         info.SetCopyright(_('Copyright (c) X.P. 2018'))
  67         info.SetIcon(wx.Icon('bitmaps/wxWidgets.png', wx.BITMAP_TYPE_PNG))
  68 
  69         wx.adv.AboutBox(info)
  70 
  71 #---------------------------------------------------------------------------
  72 
  73 class MyApp(wx.App):
  74     locale = None
  75 
  76     def OnInit(self):
  77         print('Running wxPython ' + wx.version())
  78         # Set Current directory to the one containing this file
  79         os.chdir(os.path.dirname(os.path.abspath(__file__)))
  80 
  81         self.SetAppName('Internat')
  82 
  83         self.InitLanguage()
  84 
  85         # Create the main window
  86         frm = MyFrame()
  87         self.SetTopWindow(frm)
  88 
  89         frm.Show()
  90         return True
  91 
  92     def InitLanguage(self):
  93         langsAvail = {
  94             "System default" : wx.LANGUAGE_DEFAULT,
  95             "English"        : wx.LANGUAGE_ENGLISH,
  96             "French"         : wx.LANGUAGE_FRENCH,
  97             "German"         : wx.LANGUAGE_GERMAN,
  98             "Italian"        : wx.LANGUAGE_ITALIAN,
  99         }
 100 
 101         sel = wx.GetSingleChoice("Please choose language:", "Language", list(langsAvail.keys()))
 102         if sel == "":
 103             sel = "System default"
 104 
 105         lang = langsAvail[sel]
 106         # We don't have to do anything if the selected language is english
 107         # As the strings of this app have been written in this lang
 108         if lang == wx.LANGUAGE_ENGLISH:
 109             return
 110 
 111         wx.Locale.AddCatalogLookupPathPrefix("langs")
 112         self.locale = wx.Locale()
 113         if not self.locale.Init(lang):
 114             wx.LogWarning("This language is not supported by the system.")
 115         if not self.locale.AddCatalog("internat"):
 116             wx.LogError("Couldn't find/load the 'internat' catalog for locale '" + self.locale.GetCanonicalName() + "'.")
 117 
 118 #---------------------------------------------------------------------------
 119 
 120 if __name__ == '__main__':
 121     app = MyApp()
 122     app.MainLoop()


Second example

img_sample_two.png

   1 # sample_two.py
   2 
   3 """
   4 
   5 Author  : Werner F Bruhin <wernerfbd@gmx.ch>
   6           Modified and updated by Ecco
   7 Purpose : Demonstrating i18n
   8 Created : 15/04/2014 (d/m/y)
   9 Updated : 11/09/2019 (d/m/y)
  10 
  11 """
  12 
  13 import os
  14 import sys
  15 import configparser
  16 import wx
  17 import wx.lib.sized_controls as SC
  18 import wx.lib.mixins.inspection as WIT
  19 
  20 _ = wx.GetTranslation
  21 
  22 # def _displayHook
  23 # class MyDialog
  24 # class MyFrame
  25 # class MyApp
  26 
  27 #---------------------------------------------------------------------------
  28 
  29 # Install a custom displayhook to keep Python from setting the global
  30 # _ (underscore) to the value of the last evaluated expression.
  31 # If we don't do this, our mapping of _ to gettext can get overwritten.
  32 # This is useful/needed in interactive debugging with PyShell.
  33 def _displayHook(obj):
  34     """
  35     Custom display hook to prevent Python stealing '_'.
  36     """
  37 
  38     if obj is not None:
  39         print(repr(obj))
  40 
  41 
  42 if hasattr(sys, "frozen"):
  43     basedir = os.getcwd()
  44 else:
  45     basedir, f = os.path.split(__file__)
  46 
  47 #---------------------------------------------------------------------------
  48 
  49 class MyDialog(SC.SizedDialog):
  50     """
  51     The dialog for the i18n demo.
  52     """
  53     def __init__(self, parent, id):
  54         super(MyDialog, self).__init__(None, -1,
  55                                        _("SizedForm MyDialog"),
  56                                        style=wx.DEFAULT_DIALOG_STYLE |
  57                                              wx.RESIZE_BORDER)
  58 
  59         #------------
  60 
  61         # Simplified init method.
  62         self.SetProperties()
  63         self.CreateCtrls()
  64         self.DoLayout()
  65 
  66     #-----------------------------------------------------------------------
  67 
  68     def SetProperties(self):
  69         """
  70         Set properties for my dialog.
  71         """
  72 
  73         self.SetMinSize((255, 255))
  74 
  75 
  76     def CreateCtrls(self):
  77         """
  78         ...
  79         """
  80 
  81         pane = self.GetContentsPane()
  82         pane.SetSizerType("form")
  83 
  84         #------------
  85 
  86         # Row 1.
  87         wx.StaticText(pane, -1, _("Name"))
  88         self.textCtrl = wx.TextCtrl(pane, -1, _("Your name here"))
  89 
  90         # Row 2.
  91         wx.StaticText(pane, -1, _("Email"))
  92         self.emailCtrl = wx.TextCtrl(pane, -1, "")
  93 
  94         # Row 3.
  95         wx.StaticText(pane, -1, _("Gender"))
  96         wx.Choice(pane, -1, size=(100, -1), choices=["male", "female"])
  97 
  98         # Row 4.
  99         wx.StaticText(pane, -1, _("State"))
 100         wx.TextCtrl(pane, -1, size=(100, -1)) # Two chars for state.
 101 
 102         # Row 5.
 103         wx.StaticText(pane, -1, _("Title"))
 104 
 105         # Here's how to add a "nested sizer using sized_controls.
 106         self.radioPane = SC.SizedPanel(pane, -1)
 107 
 108         # Make these children of the radioPane to
 109         # have them use the horizontal layout.
 110         wx.RadioButton(self.radioPane, -1, _("Mr."))
 111         wx.RadioButton(self.radioPane, -1, _("Mrs."))
 112         wx.RadioButton(self.radioPane, -1, _("Dr."))
 113         # End row 5.
 114 
 115         # Add dialog buttons.
 116         self.SetButtonSizer(self.CreateStdDialogButtonSizer(wx.OK | wx.CANCEL))
 117 
 118 
 119     def DoLayout(self):
 120         """
 121         ...
 122         """
 123 
 124         self.textCtrl.SetSizerProps(expand=True)
 125         self.emailCtrl.SetSizerProps(expand=True)
 126         self.radioPane.SetSizerType("horizontal")
 127         self.radioPane.SetSizerProps(expand=True)
 128 
 129         # A little trick to make sure that you can't resize the
 130         # dialog to less screen space than the controls need.
 131         self.Fit()
 132 
 133 #---------------------------------------------------------------------------
 134 
 135 class MyFrame(SC.SizedFrame):
 136     """
 137     The main frame for the i18n demo.
 138     """
 139     def __init__(self, *args, **kwargs):
 140         """
 141         Constructor.
 142         """
 143         super(MyFrame, self).__init__(*args, **kwargs)
 144 
 145         #------------
 146 
 147         # Return ini file.
 148         self.cf = os.path.join(basedir, "i18nconfig.ini")
 149         # Get a config object.
 150         self.config = configparser.ConfigParser()
 151         # Read the file "i18nconfig.ini".
 152         self.config.read(self.cf)
 153 
 154         #------------
 155 
 156         # Simplified init method.
 157         self.SetProperties()
 158         self.CreateCtrls()
 159         self.BindEvents()
 160         self.DoLayout()
 161 
 162     #-----------------------------------------------------------------------
 163 
 164     def SetProperties(self):
 165         """
 166         Set properties for my frame.
 167         """
 168 
 169         self.SetIcon(wx.Icon('icons/wxwin.ico'))
 170         self.SetMinSize((320, 170))
 171 
 172 
 173     def CreateCtrls(self):
 174         """
 175         ...
 176         """
 177 
 178         sp = self.GetContentsPane()
 179 
 180         #------------
 181 
 182         self.niceLbl = wx.StaticText(sp, wx.ID_ANY, _("Some nice text to translate"))
 183         self.btn = wx.Button(sp, wx.ID_ANY, _("Click to start a dialog"))
 184         self.langLbl = wx.StaticText(sp, label=_("Language :"))
 185 
 186         #------------
 187 
 188         langList = ["English", "Deutsche", "French"]
 189         langList.sort()
 190 
 191         self.cbLang = wx.ComboBox(sp,
 192                                   choices=langList,
 193                                   style=wx.CB_READONLY,
 194                                   size=(240, -1))
 195         # Read the value from section "Settings", option "language".
 196         oldLang = self.config.get("Settings", "language")
 197         print("Current program language : %s" % oldLang)
 198         self.cbLang.SetValue(oldLang)
 199         self.cbLang.Layout()
 200 
 201         #------------
 202 
 203         self.infoLbl = wx.StaticText(sp, label=_("Quit and restart program."))
 204         self.infoLbl.SetForegroundColour("red")
 205 
 206 
 207     def BindEvents(self):
 208         """
 209         Bind all the events related to my frame.
 210         """
 211 
 212         self.btn.Bind(wx.EVT_BUTTON, self.OnButton)
 213         self.Bind(wx.EVT_COMBOBOX, self.OnComboBox, self.cbLang)
 214 
 215 
 216     def DoLayout(self):
 217         """
 218         ...
 219         """
 220 
 221         self.niceLbl.SetSizerProps(align="center")
 222         self.btn.SetSizerProps(align="center")
 223         self.langLbl.SetSizerProps(align="center")
 224         self.cbLang.SetSizerProps(align="center")
 225         self.infoLbl.SetSizerProps(align="center")
 226 
 227         self.Fit()
 228 
 229 
 230     def OnComboBox(self, event):
 231         """
 232         ComboBox handler.
 233         """
 234 
 235         newLang = self.cbLang.GetValue()
 236         print("New program language : %s" % newLang)
 237 
 238         # Set the value to "language".
 239         self.config.set("Settings", "language", value=self.cbLang.GetValue())
 240 
 241         # Rewrite the configuration to the ".ini" file.
 242         with open(self.cf, "w") as config_file:
 243             self.config.write(config_file)
 244 
 245 
 246     def OnButton(self, event):
 247         """
 248         Button handler.
 249         """
 250 
 251         with MyDialog(self, wx.ID_ANY) as dlg:
 252             dlg.ShowModal()
 253 
 254 #---------------------------------------------------------------------------
 255 
 256 class MyApp(WIT.InspectableApp):
 257     """
 258     The Application, using WIT to help debugging.
 259     """
 260     def OnInit(self):
 261         """
 262         Do application initialization work, e.g. define application globals.
 263         """
 264 
 265         # Simplified init method.
 266         self.InitConfig()
 267         self.Init() # InspectionMixin
 268         # work around for Python stealing "_".
 269         sys.displayhook = _displayHook
 270 
 271         #------------
 272 
 273         # Return locale folder.
 274         localeDir = os.path.join(basedir, "locale")
 275 
 276         # Set language stuff and update to last used language.
 277         self.locale = None
 278         wx.Locale.AddCatalogLookupPathPrefix(localeDir)
 279         self.UpdateLanguage(self.appConfig.get("Settings", "language"))
 280 
 281         return True
 282 
 283     #-----------------------------------------------------------------------
 284 
 285     def InitConfig(self):
 286         """
 287         Initialize a configuration file if not present.
 288         """
 289 
 290         cf = os.path.join(basedir, "i18nconfig.ini")
 291 
 292         if not os.path.exists(cf):
 293             config = configparser.ConfigParser()
 294             config.add_section("Settings")
 295             # Set the default value to "language".
 296             config.set("Settings", "language", "English")
 297             # Write the configuration to the ".ini" file.
 298             with open(cf, "w") as config_file:
 299                 config.write(config_file)
 300 
 301         self.appConfig = configparser.ConfigParser()
 302         self.appConfig.read(cf)
 303 
 304 
 305     def UpdateLanguage(self, lang):
 306         """
 307         Update language locale.
 308         """
 309 
 310         # The key has to match the folder name, so you
 311         # could also use 'de_de', 'de_ch' etc if needed.
 312         supportedLangs = {"English": wx.LANGUAGE_ENGLISH,
 313                           "Deutsche": wx.LANGUAGE_GERMAN,
 314                           "French": wx.LANGUAGE_FRENCH,
 315                          }
 316 
 317         # Make *sure* any existing locale is deleted before the new
 318         # one is created. The old C++ object needs to be deleted
 319         # before the new one is created, and if we just assign a new
 320         # instance to the old Python variable, the old C++ locale will
 321         # not be destroyed soon enough, likely causing a crash.
 322         if self.locale:
 323             assert sys.getrefcount(self.locale) <= 2
 324             del self.locale
 325 
 326         # Create a locale object for this language.
 327         if supportedLangs[lang]:
 328             self.locale = wx.Locale(supportedLangs[lang])
 329             if self.locale.IsOk():
 330                 self.locale.AddCatalog("i18nDemo")
 331             else:
 332                 self.locale = None
 333         else:
 334             log.error("Requested language is not supported: %s" % lang)
 335 
 336 #---------------------------------------------------------------------------
 337 
 338 if __name__ == "__main__":
 339     app = MyApp()
 340     frm = MyFrame(None, title=_("A nice frame title"))
 341     frm.Show()
 342     app.MainLoop()


Third example

img_sample_three.png

   1 # sample_three.py
   2 
   3 """
   4 
   5 Author  : Werner F. Bruhin <wernerfbd@gmx.ch>
   6           Modified and updated by Ecco
   7 Purpose : How to I18N enable an application
   8 Created : 04/06/2012 (d/m/y)
   9 Updated : 11/09/2019 (d/m/y)
  10 
  11 Inspired by the I18N wxPython demo and the
  12 Internationalization page on the wxPython wiki.
  13 
  14 """
  15 
  16 import os
  17 import sys
  18 import wx
  19 import wx.lib.sized_controls as sc
  20 from wx.lib.mixins.inspection import InspectionMixin
  21 import wx.adv
  22 
  23 # def _displayHook
  24 # class MyFrame
  25 # class MyApp
  26 
  27 #---------------------------------------------------------------------------
  28 
  29 # Install a custom displayhook to keep Python from setting the global
  30 # _ (underscore) to the value of the last evaluated expression.
  31 # If we don't do this, our mapping of _ to gettext can get overwritten.
  32 # This is useful/needed in interactive debugging with PyShell.
  33 def _displayHook(obj):
  34     """
  35     Custom display hook to prevent Python stealing '_'.
  36     """
  37 
  38     if obj is not None:
  39         print(repr(obj))
  40 
  41 # Add translation macro to builtin similar to what gettext does.
  42 import builtins
  43 builtins.__dict__['_'] = wx.GetTranslation
  44 
  45 #---------------------------------------------------------------------------
  46 
  47 class MyFrame(sc.SizedFrame):
  48     """
  49     The main frame for the i18n demo.
  50     """
  51     def __init__(self, parent, **kwds):
  52         """
  53         A sample application to demonstrate how to enable I18N support.
  54         """
  55         super(MyFrame, self).__init__(parent, **kwds)
  56 
  57         #------------
  58 
  59         self.appName = "I18N sample application"
  60 
  61         #------------
  62 
  63         # Configuration folder.
  64         sp = wx.StandardPaths.Get()
  65         self.configLoc = sp.GetUserConfigDir()
  66         self.configLoc = os.path.join(self.configLoc, self.appName)
  67         # Win: C:\Users\userid\AppData\Roaming\appName
  68         # Nix: \home\userid\appName
  69 
  70         # AppConfig stuff is here.
  71         self.appConfig = wx.FileConfig(appName=self.appName,
  72                                        vendorName="Who you wish",
  73                                        localFilename=os.path.join(self.configLoc,
  74                                                                   "AppConfig"))
  75 
  76         #------------
  77 
  78         # Simplified init method.
  79         self.SetProperties()
  80         self.CreateMenu()
  81         self.CreateCtrls()
  82         self.BindEvents()
  83         self.DoLayout()
  84 
  85     #-----------------------------------------------------------------------
  86 
  87     def SetProperties(self):
  88         """
  89         Set properties for my frame.
  90         """
  91 
  92         self.SetTitle(_("The I18N sample application"))
  93         self.SetIcon(wx.Icon('icons/wxwin.ico'))
  94         self.SetSize((440, 240))
  95         self.SetMinSize((440, 240))
  96 
  97 
  98     def CreateMenu(self):
  99         """
 100         Make menu for my frame.
 101         """
 102 
 103         menubar = wx.MenuBar()
 104 
 105         # File menu.
 106         fileMenu = wx.Menu()
 107         closeMenuItem = fileMenu.Append(-1,
 108                                         _("Close"),
 109                                         _("Close the application"))
 110         self.Bind(wx.EVT_MENU, self.OnClose, closeMenuItem)
 111         menubar.Append(fileMenu, _("&File"))
 112 
 113         # Edit menu.
 114         manageMenu = wx.Menu()
 115         manageSomethingMenuItem = manageMenu.Append(-1,
 116                                             _("Edit something"),
 117                                             _("Edit an entry of something"))
 118         self.Bind(wx.EVT_MENU, self.OnEditSomething, manageSomethingMenuItem)
 119 
 120         menubar.Append(manageMenu, _("&Edit"))
 121 
 122         # Help menu.
 123         helpMenu = wx.Menu()
 124         aboutMenuItem = helpMenu.Append(-1,
 125                                         _("&About"),
 126                                         _("About the program"))
 127         self.Bind(wx.EVT_MENU, self.OnAboutBox, aboutMenuItem)
 128         menubar.Append(helpMenu, _("&Help"))
 129 
 130         self.SetMenuBar(menubar)
 131 
 132 
 133     def CreateCtrls(self):
 134         """
 135         ...
 136         """
 137 
 138         pane = self.GetContentsPane()
 139 
 140         #------------
 141 
 142         cPane = sc.SizedPanel(pane)
 143         cPane.SetSizerType("grid", options={"cols": 2})
 144         cPane.SetSizerProps(align="center")
 145 
 146         #------------
 147 
 148         self.st = wx.StaticText(cPane, wx.ID_ANY, _("A nice label for the TextCtrl"))
 149 
 150         self.tc = wx.TextCtrl(cPane, wx.ID_ANY, size=(220, -1))
 151 
 152         self.searchSt = wx.StaticText(cPane, wx.ID_ANY, _("a search control"))
 153 
 154         self.searchC = wx.SearchCtrl(cPane, wx.ID_ANY, size=(220, -1))
 155 
 156         self.sline = wx.StaticLine(pane, wx.ID_ANY)
 157 
 158         self.btn = wx.Button(pane, wx.ID_ANY, _("Open a file dialog"))
 159 
 160         self.langLbl = wx.StaticText(pane, label=_("Language :"))
 161 
 162         #------------
 163 
 164         langList = ["English", "Deutsche", "French"]
 165         langList.sort()
 166 
 167         self.cbLang = wx.ComboBox(pane,
 168                                   choices=langList,
 169                                   style=wx.CB_READONLY,
 170                                   size=(240, -1))
 171         # Read the value from key "Language".
 172         oldLang = self.appConfig.Read(key="Language")
 173         print("Current program language : %s" % oldLang)
 174         self.cbLang.SetValue(oldLang)
 175         self.cbLang.Layout()
 176 
 177         #------------
 178 
 179         self.infoLbl = wx.StaticText(pane, label=_("Quit and restart program."))
 180         self.infoLbl.SetForegroundColour("red")
 181 
 182 
 183     def BindEvents(self):
 184         """
 185         Bind all the events related to my frame.
 186         """
 187 
 188         self.btn.Bind(wx.EVT_BUTTON, self.OnButton)
 189         self.Bind(wx.EVT_COMBOBOX, self.OnComboBox, self.cbLang)
 190 
 191 
 192     def DoLayout(self):
 193         """
 194         ...
 195         """
 196 
 197         self.st.SetSizerProps(valign="center")
 198         self.searchSt.SetSizerProps(valign="center")
 199         self.sline.SetSizerProps(expand=True)
 200         self.btn.SetSizerProps(align="center")
 201         self.cbLang.SetSizerProps(align="center")
 202         self.infoLbl.SetSizerProps(align="center")
 203         self.langLbl.SetSizerProps(align="center")
 204 
 205         # A little trick to make sure that you can't resize the
 206         # dialog to less screen space than the controls need.
 207         self.Fit()
 208 
 209 
 210     def OnComboBox(self, event):
 211         """
 212         ComboBox handler.
 213         """
 214 
 215         newLang = self.cbLang.GetValue()
 216         print("New program language : %s" % newLang)
 217 
 218         # Set the value to "Language".
 219         self.appConfig.Write(key="Language", value=self.cbLang.GetValue())
 220         self.appConfig.Flush()
 221 
 222 
 223     def OnButton(self, event):
 224         """
 225         Button handler.
 226         """
 227 
 228         wildcard = "Python source (*.py)|*.py|"     \
 229                    "Compiled Python (*.pyc)|*.pyc|" \
 230                    "SPAM files (*.spam)|*.spam|"    \
 231                    "Egg file (*.egg)|*.egg|"        \
 232                    "All files (*.*)|*.*"
 233 
 234         with wx.FileDialog(
 235             self, message=_("Choose a file"),
 236             defaultDir=os.getcwd(),
 237             defaultFile="",
 238             wildcard=wildcard,
 239             style=wx.FD_OPEN | wx.FD_MULTIPLE | wx.FD_CHANGE_DIR
 240             ) as dlg:
 241 
 242             # Show the dialog and retrieve the user response.
 243             # If it is the OK response, process the data.
 244             if dlg.ShowModal() == wx.ID_OK:
 245                 # This returns a Python list of files that were selected.
 246                 paths = dlg.GetPaths()
 247 
 248 
 249     def OnClose(self, event):
 250         """
 251         Button handler.
 252         """
 253 
 254         self.Destroy()
 255         event.Skip()
 256 
 257 
 258     def OnEditSomething(self, event):
 259         """
 260         ...
 261         """
 262 
 263         dlg = wx.MessageDialog(self, _("Hello from Python and wxPython !"),
 264                                _("Edit"),
 265                                wx.OK | wx.ICON_INFORMATION
 266                                )
 267         dlg.ShowModal()
 268         dlg.Destroy()
 269 
 270 
 271     def OnAboutBox(self, event):
 272         """
 273         ...
 274         """
 275 
 276         dlg = wx.MessageDialog(self, _("Hello from Python and wxPython !"),
 277                                _("About"),
 278                                wx.OK | wx.ICON_INFORMATION
 279                                )
 280         dlg.ShowModal()
 281         dlg.Destroy()
 282 
 283 #---------------------------------------------------------------------------
 284 
 285 class MyApp(wx.App, InspectionMixin):
 286     """
 287     The Application, using WIT to help debugging.
 288     """
 289     def OnInit(self):
 290         """
 291         Do application initialization work, e.g. define application globals.
 292         """
 293 
 294         # Name for my application.
 295         self.appName = "I18N sample application"
 296 
 297         #------------
 298 
 299         # Simplified init method.
 300         self.DoConfig()
 301         self.Init() # InspectionMixin
 302         # work around for Python stealing "_".
 303         sys.displayhook = _displayHook
 304 
 305         #------------
 306 
 307         # Set language stuff and update to last used language.
 308         self.locale = None
 309         wx.Locale.AddCatalogLookupPathPrefix("locale")
 310         self.UpdateLanguage(self.appConfig.Read("Language"))
 311 
 312         return True
 313 
 314     #-----------------------------------------------------------------------
 315 
 316     def DoConfig(self):
 317         """
 318         Setup an application configuration file.
 319         """
 320 
 321         # Configuration folder.
 322         sp = wx.StandardPaths.Get()
 323         self.configLoc = sp.GetUserConfigDir()
 324         self.configLoc = os.path.join(self.configLoc, self.appName)
 325         # Win : C:\Users\userid\AppData\Roaming\appName
 326         # Nix : \home\userid\appName
 327 
 328         if not os.path.exists(self.configLoc):
 329             os.mkdir(self.configLoc)
 330 
 331         # AppConfig stuff is here.
 332         self.appConfig = wx.FileConfig(appName=self.appName,
 333                                        vendorName="Who you wish",
 334                                        localFilename=os.path.join(self.configLoc,
 335                                                                   "AppConfig"))
 336 
 337         if not self.appConfig.HasEntry("Language"):
 338             # On first run we default to English.
 339             self.appConfig.Write(key="Language", value="English")
 340 
 341         self.appConfig.Flush()
 342 
 343 
 344     def UpdateLanguage(self, lang):
 345         """
 346         Update the language to the requested one.
 347 
 348         Make *sure* any existing locale is deleted before the new
 349         one is created. The old C++ object needs to be deleted
 350         before the new one is created, and if we just assign a new
 351         instance to the old Python variable, the old C++ locale will
 352         not be destroyed soon enough, likely causing a crash.
 353 
 354         :param string `lang`: one of the supported language codes.
 355         """
 356 
 357         # Language domain.
 358         langDomain = "I18Nwxapp"
 359 
 360         # Languages you want to support.
 361         supLang = {"English": wx.LANGUAGE_ENGLISH,
 362                    "Deutsche": wx.LANGUAGE_GERMAN,
 363                    "French": wx.LANGUAGE_FRENCH,
 364                   }
 365 
 366         # If an unsupported language is requested default to English.
 367         if lang in supLang:
 368             selLang = supLang[lang]
 369         else:
 370             selLang = wx.LANGUAGE_ENGLISH
 371 
 372         if self.locale:
 373             assert sys.getrefcount(self.locale) <= 2
 374             del self.locale
 375 
 376         # Create a locale object for this language.
 377         self.locale = wx.Locale(selLang)
 378         if self.locale.IsOk():
 379             self.locale.AddCatalog(langDomain)
 380         else:
 381             self.locale = None
 382 
 383 #---------------------------------------------------------------------------
 384 
 385 if __name__ == "__main__":
 386     app = MyApp(redirect=False)
 387     frame = MyFrame(None)
 388     frame.Show()
 389     app.MainLoop()


   1 # geni18n.py
   2 
   3 """
   4 
   5 Author  : Werner F. Bruhin <wernerfbd@gmx.ch>
   6           Modified and updated by Ecco
   7 
   8 This will generate the .pot and .mo files for the application domain and
   9 languages defined below.
  10 
  11 The .po and .mo files are placed as per convention in
  12 
  13 "appfolder/locale/lang/LC_MESSAGES"
  14 
  15 The .pot file is placed in the locale folder.
  16 
  17 This script or something similar should be added to your build process.
  18 
  19 The actual translation work is normally done using a tool like poEdit or
  20 similar, it allows you to generate a particular language catalog from the .pot
  21 file or to use the .pot to merge new translations into an existing language
  22 catalog.
  23 
  24 """
  25 
  26 import os
  27 import sys
  28 import subprocess
  29 import wx
  30 
  31 # Language domain.
  32 langDomain = "i18nwxapp"
  33 # Languages you want to support.
  34 supLang = {"en": wx.LANGUAGE_ENGLISH,
  35            "de": wx.LANGUAGE_GERMAN,
  36            "fr": wx.LANGUAGE_FRENCH,
  37           }
  38 
  39 #---------------------------------------------------------------------------
  40 
  41 # We remove English as source code strings are in English.
  42 supportedLang = []
  43 for l in supLang:
  44     if l != "en":
  45         supportedLang.append(l)
  46 
  47 appFolder = os.getcwd()
  48 
  49 #---------------------------------------------------------------------------
  50 
  51 # Setup some stuff to get at Python I18N tools/utilities.
  52 pyExe = sys.executable
  53 pyFolder = os.path.split(pyExe)[0]
  54 pyToolsFolder = os.path.join(pyFolder, "Tools")
  55 pyI18nFolder = os.path.join(pyToolsFolder, "i18n")
  56 pyGettext = os.path.join(pyI18nFolder, "pygettext.py")
  57 pyMsgfmt = os.path.join(pyI18nFolder, "msgfmt.py")
  58 
  59 # Create folder (locale).
  60 if not os.path.exists("locale"):
  61     os.mkdir("locale")
  62 
  63 outFolder = os.path.join(appFolder, "locale")
  64 
  65 #---------------------------------------------------------------------------
  66 
  67 # Build command for pygettext.
  68 gtOptions = "-a -d %s -o %s.pot -p %s %s"
  69 tCmd = pyExe + " " + pyGettext + " " + (gtOptions % (langDomain,
  70                                                      langDomain,
  71                                                      outFolder,
  72                                                      appFolder))
  73 
  74 print ("Generating the .pot file")
  75 print ("cmd: %s" % tCmd)
  76 rCode = subprocess.call(tCmd)
  77 print ("return code: %s\n\n" % rCode)
  78 
  79 #---------------
  80 
  81 for tLang in supportedLang:
  82     # Create folders (lang\LC_MESSAGES).
  83     if not os.path.exists("locale\%s" % tLang):
  84         os.mkdir("locale\%s" % tLang)
  85     if not os.path.exists("locale\%s\LC_MESSAGES" % tLang):
  86         os.mkdir("locale\%s\LC_MESSAGES" % tLang)
  87 
  88     # Build command for msgfmt.
  89     langDir = os.path.join(appFolder, ("locale\%s\LC_MESSAGES" % tLang))
  90     poFile = os.path.join(langDir, langDomain + ".po")
  91     tCmd = pyExe + " " + pyMsgfmt + " " + poFile
  92 
  93     print ("Generating the .mo file")
  94     print ("cmd: %s" % tCmd)
  95     rCode = subprocess.call(tCmd)
  96     print ("return code: %s\n\n" % rCode)


Fourth example

img_sample_four.png

   1 # sample_four.py
   2 
   3 import sys
   4 import os
   5 import platform
   6 import wx
   7 import wx.adv
   8 from wx.lib.mixins.inspection   import InspectionMixin
   9 
  10 __version__ = "0.1"
  11 
  12 # def _displayHook
  13 # class MyPanel
  14 # class MyFrame
  15 # class MyApp
  16 
  17 #---------------------------------------------------------------------------
  18 
  19 # Install a custom displayhook to keep Python from setting the global
  20 # _ (underscore) to the value of the last evaluated expression.
  21 # If we don't do this, our mapping of _ to gettext can get overwritten.
  22 # This is useful/needed in interactive debugging with PyShell.
  23 def _displayHook(obj):
  24     """
  25     Custom display hook to prevent Python stealing '_'.
  26     """
  27 
  28     if obj is not None:
  29         print(repr(obj))
  30 
  31 # Add translation macro to builtin similar to what gettext does.
  32 import builtins
  33 builtins.__dict__['_'] = wx.GetTranslation
  34 
  35 #---------------------------------------------------------------------------
  36 
  37 class MyPanel(wx.Panel):
  38     """
  39     ...
  40     """
  41     def __init__(self, parent):
  42         super(MyPanel, self).__init__(parent)
  43 
  44         #------------
  45 
  46         # Simplified init method.
  47         self.SetProperties()
  48         self.CreateCtrls()
  49         self.BindEvents()
  50         self.DoLayout()
  51 
  52     #-----------------------------------------------------------------------
  53 
  54     def SetProperties(self):
  55         """
  56         Set the main panel properties (color...).
  57         """
  58 
  59         color = self.GetTopLevelParent().GetBackgroundColour()
  60         self.SetBackgroundColour(color)
  61 
  62 
  63     def CreateCtrls(self):
  64         """
  65         ...
  66         """
  67 
  68         bitmap_dir = wx.GetApp().GetBitmapsDir()
  69         img_path = os.path.join(bitmap_dir, "wxWidgets.png")
  70         bitmap = wx.Bitmap(img_path, type=wx.BITMAP_TYPE_PNG)
  71         self.bitmap = wx.StaticBitmap(self, bitmap=bitmap)
  72 
  73         self.label = wx.StaticText(self, label=_("Hello"))
  74 
  75         self.langlbl = wx.StaticText(self, label=_("Language :"))
  76         font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
  77         font.SetWeight(wx.BOLD)
  78         self.langlbl.SetFont(font)
  79 
  80         self.label1 = wx.StaticText(self, label=_("A nice label for test."))
  81 
  82         self.searchC = wx.SearchCtrl(self, id=wx.ID_ANY)
  83 
  84         #------------
  85 
  86         langList = ["English (U.K.)", "French"]
  87         langList.sort()
  88 
  89         self.langCh = wx.ComboBox(self,
  90                                   choices=langList,
  91                                   style=wx.CB_READONLY,
  92                                   size=(240, -1))
  93         font = wx.Font(9, wx.SWISS, wx.NORMAL, wx.NORMAL)
  94         self.langCh.SetFont(font)
  95         self.langCh.SetForegroundColour(wx.BLUE)
  96         self.langCh.Layout()
  97 
  98         config = wx.GetApp().GetConfig()
  99         lang_name = config.Read("Language")
 100 
 101         if lang_name == "LANGUAGE_ENGLISH":
 102             print("\n       Program language : %s ---> %s" % (lang_name, "en") )
 103             self.langCh.SetValue("English (U.K.)")
 104 
 105         elif lang_name == "LANGUAGE_FRENCH":
 106             print("\n       Program language : %s ---> %s" % (lang_name, "fr") )
 107             self.langCh.SetValue("French")
 108 
 109         #------------
 110 
 111         font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
 112         font.SetWeight(wx.BOLD)
 113         font.SetPointSize(9)
 114 
 115         self.btnOpen = wx.Button(self, id=wx.ID_OPEN,
 116                                  label=_("&Open a file"),
 117                                  size=(-1, -1))
 118         self.btnOpen.SetForegroundColour(wx.RED)
 119         self.btnOpen.SetFont(font)
 120 
 121         self.btnClose = wx.Button(self, id=wx.ID_CLOSE,
 122                                   label=_("&Close"),
 123                                   size=(-1, -1))
 124         self.btnClose.SetForegroundColour(wx.BLACK)
 125         self.btnClose.SetFont(font)
 126         self.btnClose.SetFocus()
 127 
 128 
 129     def BindEvents(self):
 130         """
 131         Bind all the events related to my panel.
 132         """
 133 
 134         self.Bind(wx.EVT_COMBOBOX, self.OnLang, self.langCh)
 135         self.Bind(wx.EVT_BUTTON, self.OnOpenDlg, self.btnOpen)
 136         self.Bind(wx.EVT_BUTTON, self.OnClose, self.btnClose)
 137 
 138 
 139     def DoLayout(self):
 140         """
 141         ...
 142         """
 143 
 144         vsizer = wx.BoxSizer(wx.VERTICAL)
 145         hsizer = wx.BoxSizer(wx.HORIZONTAL)
 146         langsz = wx.BoxSizer(wx.HORIZONTAL)
 147 
 148         #------------
 149 
 150         hsizer.AddStretchSpacer()
 151         hsizer.Add(self.label, 0, wx.ALIGN_CENTER)
 152         hsizer.AddStretchSpacer()
 153 
 154         #------------
 155 
 156         langsz.AddStretchSpacer()
 157         langsz.Add(self.langlbl, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
 158         langsz.Add(self.langCh, 0, wx.ALL, 5)
 159         langsz.AddStretchSpacer()
 160 
 161         #------------
 162 
 163         vsizer.AddStretchSpacer()
 164         vsizer.Add(self.bitmap, 0, wx.ALIGN_CENTER|wx.ALL, 5)
 165         vsizer.Add(self.label1, 0, wx.ALIGN_CENTER|wx.ALL, 10)
 166         vsizer.Add(self.searchC, 0, wx.ALIGN_CENTER|wx.ALL, 10)
 167         vsizer.Add(hsizer, 0, wx.EXPAND)
 168         vsizer.Add(langsz, 0, wx.EXPAND|wx.ALL, 5)
 169         vsizer.Add(self.btnOpen, 1, wx.LEFT|wx.RIGHT|wx.EXPAND, 5)
 170         vsizer.Add(self.btnClose, 1, wx.LEFT|wx.RIGHT|wx.EXPAND, 5)
 171         vsizer.AddStretchSpacer()
 172 
 173         #------------
 174 
 175         self.SetSizer(vsizer)
 176         self.Layout()
 177 
 178 
 179     def OnLang(self, event):
 180         """
 181         ...
 182         """
 183 
 184         langue = self.langCh.GetValue()
 185 
 186         if langue == "English (U.K.)":
 187             val = "LANGUAGE_ENGLISH"
 188             print("\n       Program language : %s ---> %s" % (val, "en"))
 189 
 190         elif langue == "French":
 191             val = "LANGUAGE_FRENCH"
 192             print("\n       Program language : %s ---> %s" % (val, "fr"))
 193 
 194         config = wx.GetApp().GetConfig()
 195         config.Write("Language", val)
 196 
 197 
 198     def OnOpenDlg(self, event):
 199         """
 200         ...
 201         """
 202 
 203         wildcard = "Python source (*.py)|*.py|"     \
 204                    "Compiled Python (*.pyc)|*.pyc|" \
 205                    "SPAM files (*.spam)|*.spam|"    \
 206                    "Egg file (*.egg)|*.egg|"        \
 207                    "All files (*.*)|*.*"
 208 
 209         with wx.FileDialog(
 210             self, message=_("Select a file"),
 211             defaultDir=os.getcwd(),
 212             defaultFile="",
 213             wildcard=wildcard,
 214             style=wx.FD_OPEN | wx.FD_MULTIPLE |
 215                   wx.FD_CHANGE_DIR | wx.FD_FILE_MUST_EXIST |
 216                   wx.FD_PREVIEW
 217             ) as dlg:
 218             # Show the dialog and retrieve the user response.
 219             # If it is the OK response, process the data.
 220             if dlg.ShowModal() == wx.ID_OK:
 221                 # This returns a Python list of files that
 222                 # were selected.
 223                 paths = dlg.GetPaths()
 224 
 225 
 226     def OnClose(self, event):
 227         """
 228         ...
 229         """
 230 
 231         self.GetParent().Close()
 232         event.Skip()
 233 
 234 #---------------------------------------------------------------------------
 235 
 236 class MyFrame(wx.Frame):
 237     """
 238     Main application window.
 239     """
 240     def __init__(self, parent):
 241         super(MyFrame, self).__init__(parent,
 242                                       style=wx.DEFAULT_FRAME_STYLE ^
 243                                            (wx.RESIZE_BORDER))
 244 
 245         #------------
 246 
 247         # Simplified init method.
 248         self.SetProperties()
 249         self.CreateMenu()
 250         self.CreateCtrls()
 251         self.BindEvents()
 252         self.DoLayout()
 253 
 254     #-----------------------------------------------------------------------
 255 
 256     def SetProperties(self):
 257         """
 258         Set the main frame properties (title, icon...).
 259         """
 260 
 261         self.SetTitle(_("I18N - Sample App"))
 262         self.SetBackgroundColour("")
 263 
 264         icons_dir = wx.GetApp().GetIconsDir()
 265         icon_path = os.path.join(icons_dir, "wxwin.ico")
 266         frameIcon = wx.Icon(icon_path, type=wx.BITMAP_TYPE_ICO)
 267 
 268         self.SetIcon(frameIcon)
 269 
 270 
 271     def CreateMenu(self):
 272         """
 273         ...
 274         """
 275 
 276         menubar = wx.MenuBar()
 277 
 278         #------------
 279 
 280         # File menu.
 281         fileMenu = wx.Menu()
 282         closeMenuItem = fileMenu.Append(-1,
 283                                         _("Close"),
 284                                         _("Close the application"))
 285         self.Bind(wx.EVT_MENU, self.OnClose, closeMenuItem)
 286         menubar.Append(fileMenu, _("&File"))
 287 
 288         #------------
 289 
 290         # Edit menu.
 291         manageMenu = wx.Menu()
 292         manageSomethingMenuItem = manageMenu.Append(-1,
 293                                             _("Edit something"),
 294                                             _("Edit an entry of something"))
 295         self.Bind(wx.EVT_MENU, self.DoEditSomething, manageSomethingMenuItem)
 296 
 297         menubar.Append(manageMenu, _("&Edit"))
 298 
 299         #------------
 300 
 301         # Help menu.
 302         helpMenu = wx.Menu()
 303         aboutMenuItem = helpMenu.Append(-1),
 304                                         _("&About"),
 305                                         _("About the program"))
 306         self.Bind(wx.EVT_MENU, self.DoAboutBox, aboutMenuItem)
 307         menubar.Append(helpMenu, _("&Help"))
 308 
 309         self.SetMenuBar(menubar)
 310 
 311 
 312     def CreateCtrls(self):
 313         """
 314         ...
 315         """
 316 
 317         # Add a panel so it looks the correct on all platforms.
 318         self.panel = MyPanel(self)
 319 
 320 
 321     def BindEvents(self):
 322         """
 323         Bind all the events related to my frame.
 324         """
 325 
 326         self.Bind(wx.EVT_SIZE, self.OnResize)
 327         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
 328 
 329 
 330     def DoLayout(self):
 331         """
 332         ...
 333         """
 334 
 335         sizer = wx.BoxSizer(wx.VERTICAL)
 336         sizer.Add(self.panel, 1, wx.EXPAND)
 337         self.SetSizer(sizer)
 338         self.SetInitialSize((300, 380))
 339 
 340 
 341     def OnResize(self, event):
 342         """
 343         ...
 344         """
 345 
 346         self.Refresh()
 347         event.Skip()
 348 
 349 
 350     def OnClose(self, event):
 351         """
 352         ...
 353         """
 354 
 355         self.Close()
 356         event.Skip()
 357 
 358 
 359     def DoEditSomething(self, event):
 360         """
 361         ...
 362         """
 363 
 364         dlg = wx.MessageDialog(self,
 365                                _('Hello from Python and wxPython !'),
 366                                _('Edit'),
 367                                wx.OK | wx.ICON_INFORMATION)
 368         dlg.ShowModal()
 369         dlg.Destroy()
 370 
 371 
 372     def DoAboutBox(self, event):
 373         """
 374         ...
 375         """
 376 
 377         dlg = wx.MessageDialog(self,
 378                                _('Hello from Python and wxPython !'),
 379                                _('About'),
 380                                wx.OK | wx.ICON_INFORMATION)
 381         dlg.ShowModal()
 382         dlg.Destroy()
 383 
 384 
 385     def OnCloseWindow(self, event):
 386         """
 387         ...
 388         """
 389 
 390         self.Destroy()
 391         event.Skip()
 392 
 393 #---------------------------------------------------------------------------
 394 
 395 class MyApp(wx.App, InspectionMixin):
 396     """
 397     The main application class.
 398     """
 399     def OnInit(self):
 400         """
 401         Default wx.App initialization.
 402         """
 403 
 404         # Work around for Python stealing "_".
 405         sys.displayhook = _displayHook
 406 
 407         self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]
 408 
 409         # Used to identify app in $HOME/
 410         self.SetAppName("I18NTestApp")
 411 
 412         # Get Language from last run if set.
 413         config = wx.GetApp().GetConfig()
 414         language = config.Read("Language", "LANGUAGE_DEFAULT")
 415         self.language = language
 416 
 417         # Simplified init method.
 418         self.Init()  # InspectionMixin (Ctrl+Alt+I).
 419         self.InitI18n()
 420         self.Setlang(language)
 421 
 422         # Local is not setup so we can create things
 423         # that may need it to retrieve translations.
 424         self.frame = MyFrame(None)
 425         self.SetTopWindow(self.frame)
 426         self.frame.Show(True)
 427 
 428         return True
 429 
 430     #-----------------------------------------------------------------------
 431 
 432     def InitI18n(self):
 433         """
 434         ...
 435         """
 436 
 437         # Set locale for wxWidgets.
 438         # You would define wx.Locale in your wx.App.OnInit class.
 439         # Setup the Locale
 440         self.locale = wx.Locale(getattr(wx, self.language))
 441         path = os.path.abspath("./locale") + os.path.sep
 442         self.locale.AddCatalogLookupPathPrefix(path)
 443         self.locale.AddCatalog(self.GetAppName())
 444 
 445         print('\n\nAPPLICATION :\n')
 446         print(" Name ------> %s" % self.GetAppName())
 447 
 448         print('\n\nLOCALE :\n')
 449         print(" Canonical Name ------>", self.locale.GetCanonicalName())  # fr_FR
 450         print(" Language ID ------>", self.locale.GetLanguage())  # 78
 451         print(" Locale ------>", self.locale.GetLocale())  # French
 452         print(" Name ------>", self.locale.GetName())  # fr_FR
 453 
 454 
 455     def GetVersion(self):
 456         """
 457         Return the current MyApp version.
 458         """
 459 
 460         return __version__
 461 
 462 
 463     def GetInstallDir(self):
 464         """
 465         Returns the installation directory for MyApp.
 466         """
 467 
 468         return self.installDir
 469 
 470 
 471     def GetIconsDir(self):
 472         """
 473         Returns the icons directory for MyApp.
 474         """
 475 
 476         icons_dir = os.path.join(self.installDir, "icons")
 477         return icons_dir
 478 
 479 
 480     def GetBitmapsDir(self):
 481         """
 482         Returns the bitmaps directory for MyApp.
 483         """
 484 
 485         bitmaps_dir = os.path.join(self.installDir, "bitmaps")
 486         return bitmaps_dir
 487 
 488 
 489     def GetConfigDir(self):
 490         """
 491         Returns the option directory for MyApp.
 492         """
 493 
 494         config_dir  = os.path.join(self.installDir, "config")
 495         return config_dir
 496 
 497 
 498     def GetConfig(self):
 499         """
 500         Returns the configuration for MyApp.
 501         """
 502 
 503         if not os.path.exists(self.GetConfigDir()):
 504             # Create the config folder, it still doesn't exist.
 505             os.makedirs(self.GetConfigDir())
 506 
 507         config_file = wx.FileConfig(localFilename=os.path.join(
 508                                     self.GetConfigDir(), "options"))
 509 
 510         # On first run we default to English.
 511         if not config_file.HasEntry("Language"):
 512             config_file.Write(key="Language", value="LANGUAGE_DEFAULT")
 513         config_file.Flush()
 514 
 515         return config_file
 516 
 517 
 518     def Setlang(self, language):
 519         """
 520         To get some language settings to display properly on Linux.
 521         Thanks to Ianare Sevi.
 522         """
 523 
 524         if language == "LANGUAGE_ENGLISH":
 525             if platform.system() == "Linux":
 526                 try:
 527                     # To get some language settings to display properly.
 528                     os.environ["LANGUAGE"] = "en"
 529 
 530                 except (ValueError, KeyError):
 531                     pass
 532 
 533         elif language == "LANGUAGE_FRENCH":
 534             if platform.system() == "Linux":
 535                 try:
 536                     # To get some language settings to display properly.
 537                     os.environ["LANGUAGE"] = "fr"
 538 
 539                 except (ValueError, KeyError):
 540                     pass
 541 
 542 #---------------------------------------------------------------------------
 543 
 544 def main():
 545     app = MyApp(False)
 546     app.MainLoop()
 547 
 548 #---------------------------------------------------------------------------
 549 
 550 if __name__ == "__main__":
 551     main()


Valid i18n code

The currently (wxPython 2.6.3) usable language-country code combinations are :

   1 aa      unicode: Afar
   2 ab      unicode: Abkhazian
   3 af_ZA   unicode: Afrikaans
   4 am      unicode: Amharic
   5 ar      unicode: Arabic
   6 ar_AE   unicode: Arabic (Uae)
   7 ar_BH   unicode: Arabic (Bahrain)
   8 ar_DZ   unicode: Arabic (Algeria)
   9 ar_EG   unicode: Arabic (Egypt)
  10 ar_IQ   unicode: Arabic (Iraq)
  11 ar_JO   unicode: Arabic (Jordan)
  12 ar_KW   unicode: Arabic (Kuwait)
  13 ar_LB   unicode: Arabic (Lebanon)
  14 ar_LY   unicode: Arabic (Libya)
  15 ar_MA   unicode: Arabic (Morocco)
  16 ar_OM   unicode: Arabic (Oman)
  17 ar_QA   unicode: Arabic (Qatar)
  18 ar_SA   unicode: Arabic (Saudi Arabia)
  19 ar_SD   unicode: Arabic (Sudan)
  20 ar_SY   unicode: Arabic (Syria)
  21 ar_TN   unicode: Arabic (Tunisia)
  22 ar_YE   unicode: Arabic (Yemen)
  23 as      unicode: Assamese
  24 ay      unicode: Aymara
  25 az      unicode: Azeri (Latin)
  26 ba      unicode: Bashkir
  27 be_BY   unicode: Belarusian
  28 bg_BG   unicode: Bulgarian
  29 bh      unicode: Bihari
  30 bi      unicode: Bislama
  31 bn      unicode: Bengali
  32 bo      unicode: Tibetan
  33 br      unicode: Breton
  34 ca_ES   unicode: Catalan
  35 co      unicode: Corsican
  36 cs_CZ   unicode: Czech
  37 cy      unicode: Welsh
  38 da_DK   unicode: Danish
  39 de_AT   unicode: German (Austrian)
  40 de_BE   unicode: German (Belgium)
  41 de_CH   unicode: German (Swiss)
  42 de_DE   unicode: German
  43 de_LI   unicode: German (Liechtenstein)
  44 de_LU   unicode: German (Luxembourg)
  45 dz      unicode: Bhutani
  46 el_GR   unicode: Greek
  47 en_AU   unicode: English (Australia)
  48 en_BW   unicode: English (Botswana)
  49 en_BZ   unicode: English (Belize)
  50 en_CA   unicode: English (Canada)
  51 en_CB   unicode: English (Caribbean)
  52 en_DK   unicode: English (Denmark)
  53 en_GB   unicode: English (U.K.)
  54 en_IE   unicode: English (Eire)
  55 en_JM   unicode: English (Jamaica)
  56 en_NZ   unicode: English (New Zealand)
  57 en_PH   unicode: English (Philippines)
  58 en_TT   unicode: English (Trinidad)
  59 en_US   unicode: English (U.S.)
  60 en_ZA   unicode: English (South Africa)
  61 en_ZW   unicode: English (Zimbabwe)
  62 eo      unicode: Esperanto
  63 es_AR   unicode: Spanish (Argentina)
  64 es_BO   unicode: Spanish (Bolivia)
  65 es_CL   unicode: Spanish (Chile)
  66 es_CO   unicode: Spanish (Colombia)
  67 es_CR   unicode: Spanish (Costa Rica)
  68 es_DO   unicode: Spanish (Dominican republic)
  69 es_EC   unicode: Spanish (Ecuador)
  70 es_ES   unicode: Spanish (Modern)
  71 es_GT   unicode: Spanish (Guatemala)
  72 es_HN   unicode: Spanish (Honduras)
  73 es_MX   unicode: Spanish (Mexican)
  74 es_NI   unicode: Spanish (Nicaragua)
  75 es_PA   unicode: Spanish (Panama)
  76 es_PE   unicode: Spanish (Peru)
  77 es_PR   unicode: Spanish (Puerto Rico)
  78 es_PY   unicode: Spanish (Paraguay)
  79 es_SV   unicode: Spanish (El Salvador)
  80 es_US   unicode: Spanish (U.S.)
  81 es_UY   unicode: Spanish (Uruguay)
  82 es_VE   unicode: Spanish (Venezuela)
  83 et_EE   unicode: Estonian
  84 eu_ES   unicode: Basque
  85 fa_IR   unicode: Farsi
  86 fi_FI   unicode: Finnish
  87 fj      unicode: Fiji
  88 fo_FO   unicode: Faeroese
  89 fr_BE   unicode: French (Belgian)
  90 fr_CA   unicode: French (Canadian)
  91 fr_CH   unicode: French (Swiss)
  92 fr_FR   unicode: French
  93 fr_LU   unicode: French (Luxembourg)
  94 fr_MC   unicode: French (Monaco)
  95 fy      unicode: Frisian
  96 ga_IE   unicode: Irish
  97 gd      unicode: Scots Gaelic
  98 gl_ES   unicode: Galician
  99 gn      unicode: Guarani
 100 gu      unicode: Gujarati
 101 ha      unicode: Hausa
 102 he_IL   unicode: Hebrew
 103 hi_IN   unicode: Hindi
 104 hr_HR   unicode: Croatian
 105 hu_HU   unicode: Hungarian
 106 hy      unicode: Armenian
 107 ia      unicode: Interlingua
 108 id_ID   unicode: Indonesian
 109 ie      unicode: Interlingue
 110 ik      unicode: Inupiak
 111 is_IS   unicode: Icelandic
 112 it_CH   unicode: Italian (Swiss)
 113 it_IT   unicode: Italian
 114 iu      unicode: Inuktitut
 115 ja_JP   unicode: Japanese
 116 jw      unicode: Javanese
 117 ka      unicode: Georgian
 118 kk      unicode: Kazakh
 119 kl_GL   unicode: Greenlandic
 120 km      unicode: Cambodian
 121 kn      unicode: Kannada
 122 ko_KR   unicode: Korean
 123 ks      unicode: Kashmiri
 124 ks_IN   unicode: Kashmiri (India)
 125 ku      unicode: Kurdish
 126 kw_GB   unicode: Kernewek
 127 ky      unicode: Kirghiz
 128 la      unicode: Latin
 129 ln      unicode: Lingala
 130 lo      unicode: Laothian
 131 lt_LT   unicode: Lithuanian
 132 lv_LV   unicode: Latvian
 133 mg      unicode: Malagasy
 134 mi      unicode: Maori
 135 mk_MK   unicode: Macedonian
 136 ml      unicode: Malayalam
 137 mn      unicode: Mongolian
 138 mo      unicode: Moldavian
 139 mr_IN   unicode: Marathi
 140 ms_BN   unicode: Malay (Brunei Darussalam)
 141 ms_MY   unicode: Malay (Malaysia)
 142 mt_MT   unicode: Maltese
 143 my      unicode: Burmese
 144 na      unicode: Nauru
 145 nb_NO   unicode: Norwegian (Bokmal)
 146 ne      unicode: Nepali
 147 ne_IN   unicode: Nepali (India)
 148 nl_BE   unicode: Dutch (Belgian)
 149 nl_NL   unicode: Dutch
 150 nn_NO   unicode: Norwegian (Nynorsk)
 151 oc      unicode: Occitan
 152 om      unicode: (Afan) Oromo
 153 or      unicode: Oriya
 154 pa      unicode: Punjabi
 155 pl_PL   unicode: Polish
 156 ps      unicode: Pashto, Pushto
 157 pt_BR   unicode: Portuguese (Brazilian)
 158 pt_PT   unicode: Portuguese
 159 qu      unicode: Quechua
 160 rm      unicode: Rhaeto-Romance
 161 rn      unicode: Kirundi
 162 ro_RO   unicode: Romanian
 163 ru_RU   unicode: Russian
 164 ru_UA   unicode: Russian (Ukraine)
 165 rw      unicode: Kinyarwanda
 166 sa      unicode: Sanskrit
 167 sd      unicode: Sindhi
 168 sg      unicode: Sangho
 169 sh      unicode: Serbo-Croatian
 170 si      unicode: Sinhalese
 171 sk_SK   unicode: Slovak
 172 sl_SI   unicode: Slovenian
 173 sm      unicode: Samoan
 174 sn      unicode: Shona
 175 so      unicode: Somali
 176 sq_AL   unicode: Albanian
 177 sr_YU   unicode: Serbian (Latin)
 178 ss      unicode: Siswati
 179 st      unicode: Sesotho
 180 su      unicode: Sundanese
 181 sv_FI   unicode: Swedish (Finland)
 182 sv_SE   unicode: Swedish
 183 sw_KE   unicode: Swahili
 184 ta      unicode: Tamil
 185 te      unicode: Telugu
 186 tg      unicode: Tajik
 187 th_TH   unicode: Thai
 188 ti      unicode: Tigrinya
 189 tk      unicode: Turkmen
 190 tl_PH   unicode: Tagalog
 191 tn      unicode: Setswana
 192 to      unicode: Tonga
 193 tr_TR   unicode: Turkish
 194 ts      unicode: Tsonga
 195 tt      unicode: Tatar
 196 tw      unicode: Twi
 197 ug      unicode: Uighur
 198 uk_UA   unicode: Ukrainian
 199 ur      unicode: Urdu
 200 ur_IN   unicode: Urdu (India)
 201 ur_PK   unicode: Urdu (Pakistan)
 202 uz      unicode: Uzbek (Latin)
 203 vi_VN   unicode: Vietnamese
 204 vo      unicode: Volapuk
 205 wo      unicode: Wolof
 206 xh      unicode: Xhosa
 207 yi      unicode: Yiddish
 208 yo      unicode: Yoruba
 209 za      unicode: Zhuang
 210 zh_CN   unicode: Chinese (Simplified)
 211 zh_HK   unicode: Chinese (Hongkong)
 212 zh_MO   unicode: Chinese (Macau)
 213 zh_SG   unicode: Chinese (Singapore)
 214 zh_TW   unicode: Chinese (Traditional)
 215 zu      unicode: Zulu


Download source

source.zip


Additional Information

For the non-ascii characters, save the text file with an utf-8 encoding.

For the translation or editing, you can use Poedit application.

It exist some version for Windows, Mac and Linux.

- - - - -

1 - The word internationalization is often abbreviated as I18N : Take the first letter of the word (i) followed by the number of letters in the word (18) and terminate it with the last letter of the word (n).

2 - MO stands for Machine Object file.

3 - PO stands for Portable Object file.

4 - The translation domain corresponds to the .mo dictionary file that is searched by the _() gettext translation function. It is selected by gettext.install()

- - - - -

Link :

https://en.wikipedia.org/wiki/Poedit

https://fr.wikipedia.org/wiki/Poedit

https://wiki.wxpython.org/Internationalization

http://wiki.laptop.org/go/Python_i18n

http://zetcode.com/wxpython/in18/

https://docs.wxpython.org/internationalization.html

See RecipesI18n

- - - - -

https://wiki.wxpython.org/TitleIndex

https://docs.wxpython.org/


Thanks to

Xaviou (sample_one.py coding), Werner F. Bruhin (sample_two / three.py coding), Cody Precord, Robin Dunn, Andrea Gavana, ZetCode, the wxPython community...


About this page

Date(d/m/y) Person (bot) Comments :

28/08/19 - Ecco (Created page for wxPython Phoenix).


Comments

- blah, blah, blah....

Internationalization - i18n (Phoenix) (last edited 2020-10-07 10:15:35 by Ecco)

NOTE: To edit pages in this wiki you must be a member of the TrustedEditorsGroup.