boom
boom

Reputation: 6166

In GTK, how do I change the localized language text on the UI while it's running?

In Linux, is it possible to change the UI language on the fly which is created using GTK? I have a application which needs to change UI language on the fly.

Upvotes: 4

Views: 3697

Answers (4)

aloplop85
aloplop85

Reputation: 922

I changed the language on the fly, following these steps:

  1. Create a .po file containing key-value pairs for the translations:

    msgid "Yes" msgstr "Ja"

  2. Use msgfmt in order to obtain a .mo file, which must be moved into the corresponing LC_MESSAGES folder of the locale (e.g. /usr/share/locale/de/LC_MESSAGES):

    msgfmt myapp.po - o myapp.mo

  3. Bind this file to the application:

    #define ENABLE_NLS
    
    #ifdef ENABLE_NLS
    
    
        #include <libintl.h>
                #include <locale.h>
                #define PACKAGE_LOCALE_DIR "/usr/share/locale"
    
                // "myapp" is the mo file name in LOCALE
                #define GETTEXT_PACKAGE    "myapp"
    
                #  undef _
                #  define _(String) dgettext (GETTEXT_PACKAGE, String)
                #  ifdef gettext_noop
                #    define N_(String) gettext_noop (String)
                #  else
                #    define N_(String) (String)
                #  endif
    
    #else
    #  define textdomain(String) (String)
    #  define gettext(String) (String)
    #  define dgettext(Domain,Message) (Message)
    #  define dcgettext(Domain,Message,Type) (Message)
    #  define bindtextdomain(Domain,Directory) (Domain)
    #  define _(String) (String)
    #  define N_(String) (String)
    #endif
    
  4. Whenever the language must be changed, call these methods:

    if(setlocale(LC_ALL, language)==NULL)
    {
        printf("--> changeLAnguage: ERROR !!!\r\n");
        return false;
    }
    
    setenv("LANGUAGE", language, true);
    setenv("LANG", language, true);
    setenv("LC_ALL", language, true);
    setenv("LC_MESSAGES", language, true);
    setlocale(LC_ALL, "");
    
  5. Set the text of the labels by using the msgids in the .po file:

    SetTextOfLabel("label1", _(MSG_ID_1));
    

    For example,

    gtk_label_set_text(GTK_LABEL(widget),str);
    

HTH

Upvotes: 1

frang
frang

Reputation: 97

You can use NAppGUI, that supports runtime translations in Windows (WinAPI), macOS (Cocoa) and Linux (Gtk).

http://nappgui.com/es/demo/products.html#h4.5

Upvotes: 0

ptomato
ptomato

Reputation: 57870

You'll have to either destroy all your widgets and rebuild them with the new locale setting, or manually change all the strings to their translated equivalents. It is best to do this with gettext.

Many applications choose not to offer a setting for the UI language inside the application. Instead, they just follow the system language setting.

Upvotes: 1

Jeff Halverson
Jeff Halverson

Reputation: 253

It is certainly possible, you just have to put a little work into it.

As an example, if you are using c#, you would first need to ensure all translatable items are included in a Mono.Unix.Catalog.GetString function. A typical Label, would look like this:

Gtk.Label label1 = new Gtk.Label(Mono.Unix.Catalog.GetString("Monkey Juice"));
Gtk.Label label2 = new Gtk.Label(Mono.Unix.Catalog.GetString("Squirrel Love"));

When you do this, as long as you have the proper translation file (.po files) you will have the application startup in the current locale. Now, if you want to change the locale from within the application, you just need to have a function that does this:

void ChangeToJapanese() {
     System.Globalization.CultureInfo ci = new System.Globalization.CultureInfo(" ja_JP");
     System.Threading.Thread.CurrentThread.CurrentCulture = ci;
     label1.Text = Mono.Unix.Catalog.GetString("Monkey Juice");
     label2.Text = Mono.Unix.Catalog.GetString("Squirrel Love");
}

Now, your application should change so your labels would show 猿ジュース and リスの愛.

Upvotes: 1

Related Questions