esnadr
esnadr

Reputation: 445

How to translate pygtk; glade; gtk.Builder() application?

This is my first trial in translating pygtk glade; I have created Rockdome.mo file on the following dir:./locale/ar/LC_MESSAGES/Rockdome.mo

    def apply_locale(self , lang):
         domain  = "Rockdome"
         local_path = basefolder+"/locale"   # basefolder is the current dir
         lang = gettext.translation('Rockdome', local_path ,  languages=['%s'%lang])
         lang.install()
         _ = lang.gettext
         print _("Close") # the output is اغلاق which is correct arabic translation!!

but the application still appear in the default system lamnguage EN; What I missing ??

EDIT

After searching in pygtk and buider tutoial; I found 2 methods to tell gtk & builder How to bring text : the first from here :

 for module in (gettext, gtk.glade):
     module.bindtextdomain(APP_NAME, LOCALE_DIR)
     module.textdomain(APP_NAME)       

which fail.


The second from here

 self.builder.set_translation_domain('Rockdome')
 print self.builder.get_translation_domain() # the output is "Rockdome"

which also fail !!, the application still untranslated !!

N.B: I guess that builder needs to know the location for my local path to search in it not in the default paths so I copied ./local/ar/LC_MESSAGES/Rockdome.mo to /usr/share/locale/ar/LC_MESSAGES/Rockdome.mo which also failed.

Upvotes: 4

Views: 1560

Answers (2)

esnadr
esnadr

Reputation: 445

the following method works succefully with me >

  1. use locale module not gettext.
  2. execute locale.setlocale(category , language )
  3. Set the translation_domain of gtk.Builder by gtk.Builder.set_translation_domain() before loading glade file by : EX:gtk.Builder.add_from_file

Code ##

    import locale
    from locale import gettext as _

    def apply_locale(self , current_lang ):
        domain  = "Rockdome"
        local_path = basefolder+"/data/locale"
        locale.bindtextdomain(domain , local_path )
        locale.textdomain(domain)
        locale.setlocale(locale.LC_ALL, 'ar_AE.utf8')   
        # note that language is "ar_AE.utf8" not "ar" or "ar_AE"
        self.builder.set_translation_domain(domain )

Why we should replace gettext with locale

Thanks to Juha Sahakangas on the #gtk+ IRC channel for providing the explanation: For this particular case the locale module needs to be used instead of gettext. Python's gettext module is pure python, it doesn't actually set the text domain in a way that the C library can read, but locale does (by calling libc). So long as that's done, GtkBuilder already works the way you're asking it to.


Notes

to avoid locale.Error: unsupported locale setting

  1. In the function locale.setlocale(locale.LC_ALL, language ); language should be one the supported languages.
  2. to get list of supported languages; locale -a command.

  3. The name of the language should be equal to its name in the output of the command locale -a; ie. don't strip the encode if it included in the language name, ie:. ar_AE.utf8 doesn't equal to ar_AE.

  4. If the language doesn't supported; we can install it.

  5. To install unsupported language:

sudo apt-get install language-pack-en-base

sudo dpkg-reconfigure locales

Thanks for this links

how to make glade load translation

locale error : unsupported locale setting

locale module doc

install unsupported locale

Upvotes: 4

The_Cthulhu_Kid
The_Cthulhu_Kid

Reputation: 1859

You are only changing the lang object within the scope of the function. You have to return it to set it properly.

You need to call your function like this: my_lang = apply_locale(lang) or you could set lang as a property of the class.

def apply_locale(self , lang):
     domain  = "Rockdome"
     local_path = basefolder+"/locale"   # basefolder is the current dir
     lang = gettext.translation('Rockdome', local_path ,  languages=['%s'%lang])
     lang.install()
     _ = lang.gettext
     return lang  # Here you return the value and set it to the object you passed to your function.

Your use of the variable name here is confusing. You are changing the argument to a completely different type of object, you might want to differentiate between the two.

Upvotes: 1

Related Questions