Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Autor: MrPoxipol
Biblioteki C++

Tworzenie aplikacji obsługującej wiele języków

[lekcja] Rozdział omawia w jaki sposób tworzy się aplikacje okienkowe, obsługujące wiele języków narodowych przy pomocy biblioteki GTK+.

Wprowadzenie

Często zdarza się, że chcesz, aby twoja aplikacja mogła mieć kilka (a nawet kilkanaście) wersji językowych, pytanie tylko, jak to zrobić? Pewnie wpadłeś na pomysł, aby stworzyć własne pliki językowe i ładować treść do zmiennych tekstowych, lecz takie rozwiązanie jest trochę niewygodne, gdy można użyć lepszego rozwiązania, jakim jest wykorzystanie biblioteki gettext.
W tej lekcji chciałbym Ci pokazać najprostszy sposób jak zrobić tłumaczenie do swojej aplikacji GTK+. No to zaczynamy :).

Tworzymy prosty program

Stwórzmy najpierw jakiś prosty program, na którym można by przetestować działanie naszego tłumaczenia. Do lekcji polecam Ci podany poniżej kod, aby uniknąć błędów.
Aby skompilować poniższy kod, musisz dodać do linkowanych bibliotek intl.lib. Możesz ją znaleźć w katalogu lib biblioteki GTK+.
Kod:
C/C++
#include <gtk/gtk.h>
#include <glib/gi18n.h> // Nowe!

#define GETTEXT_PACKAGE "foo" // Nazwa naszego pakietu bez rozszerzenia
#define LOCALEDIR "share/locale" // Katalog, gdzie gettext będzie szukał pakietów

int main( int argc, char * argv[] )
{
    bindtextdomain( GETTEXT_PACKAGE, LOCALEDIR ); // Ustawianie pakietu
    bind_textdomain_codeset( GETTEXT_PACKAGE, "UTF-8" );
    textdomain( GETTEXT_PACKAGE );
   
    gtk_set_locale();
   
    GtkWidget * okno, * vbox, * etykieta, * przycisk;
   
    gtk_init( & argc, & argv );
   
    okno = gtk_window_new( GTK_WINDOW_TOPLEVEL );
    gtk_window_set_position( GTK_WINDOW( okno ), GTK_WIN_POS_CENTER );
    gtk_window_set_default_size( GTK_WINDOW( okno ), 200, 50 );
    gtk_window_set_title( GTK_WINDOW( okno ), "Kurs GTK+" );
   
    etykieta = gtk_label_new( _( "Label" ) ); // Makro gettext!
    gtk_misc_set_alignment( GTK_MISC( etykieta ), 0.1, 0.5 );
   
    przycisk = gtk_button_new_with_label( _( "Button" ) );
   
    /* Umieszczenie na oknie */
    vbox = gtk_vbox_new( FALSE, 1 );
    gtk_container_set_border_width( GTK_CONTAINER( vbox ), 10 );
   
    gtk_container_add( GTK_CONTAINER( okno ), vbox );
    gtk_box_pack_start( GTK_BOX( vbox ), etykieta, TRUE, TRUE, 2 );
    gtk_box_pack_start( GTK_BOX( vbox ), przycisk, TRUE, TRUE, 2 );
    gtk_widget_show_all( okno );
   
    /* Sygnały */
    g_signal_connect( G_OBJECT( okno ), "destroy", G_CALLBACK( gtk_main_quit ), NULL );
   
    gtk_main();
    return 0;
}

Teraz czas na wyjaśnienie. Nowo dodanym nagłówkiem jest
#include <glib/gi18n.h>
. Trzema funkcjami ustawiamy domenę tekstu. Następnie ustawiamy 'locale'. Funkcja
void gtk_misc_set_alignment( GtkMisc * misc, gfloat xalign, gfloat yalign )
 odpowiada za rozstawienie obiektu typu GtkMisc (czyli również GtkLabel). Jako pierwszy argument przyjmuje widget, drugi to ustawienie na osi x, a ostatni na osi y.
Teraz najważniejsza funkcja (a właściwie makro) w naszym programie, którą jest właśnie
_( text )
, dzięki niej zaznaczamy tekst do tłumaczenia, który zostanie podmieniony w czasie, gdy program będzie uruchomiony. Więcej o tych makrach (tak, jest ich więcej ;)), możesz przeczytać w dokumentacji GLib.

Okno przed przetłumaczeniem
Okno przed przetłumaczeniem

Przygotowanie pakietów językowych

Internacjonalizacja z użyciem gettext polega na pobieraniu przez program tekstów ze skompilowanych paczek językowych, co jest szybsze. Aby najwygodniej stworzyć takie paczki potrzebujesz  programu xgettext lub nakładki na niego - Poedit. Ja opiszę tworzenie tych pakietów z użyciem tego drugiego (graficznego).

Utwórzmy nowy pakiet w programie Poedit wybierając z menu 'Plik -> Nowy katalog ...'. Następnie w 'Ustawieniach projektu' w zakładce 'Informacje o projekcie' musimy wypełnić pole 'Projekt', które będzie nazwą pakietu, opcjonalnie wypełniamy pola: Zespół, Adres e-mail. W zakładce 'Ścieżki' dodajemy katalogi, z których Poedit wyszuka źródła naszego programu, aby wyszukać zadeklarowane w trzeciej karcie słowa kluczowe (funkcji). W tejże karcie dodajemy przynajmniej jedną ścieżkę (jeśli plik .po będzie obok naszych źródeł, ustaw ścieżkę tak jak na obrazku.
Ścieżki
Ścieżki
Jeśli wykonałeś poprawnie to co wcześniej napisałem, powinien wyskoczyć dialog zapisu pliku, zapisz go tam, gdzie Ci pasuje (Pamiętaj o ścieżkach!).
Następnie Poedit powinien wyszukać wyróżnione stringi w naszym kodzie, a następnie pokazać nam taki oto dialog:
Nowe teksty
Nowe teksty
Potwierdź go klikając 'OK'.

Tłumaczenie

Tłumaczenie tekstów w Poedit jest banalnie proste i intuicyjne, wystarczy kliknąć obok, lub na wybrany przez nas obiekt i przetłumaczyć go w polu tekstowym znajdującym się niżej. Po stringach możemy poruszać się za pomocą skrótu klawiszowego 'Tab + Strzałka w górę lub w dół'. Przetłumaczmy więc nasze 2 stringi na język polski (można stworzyć więcej pakietów, dla innych języków). A następnie zapiszmy nasz projekt, co jest równoznaczne z utworzeniem binarnego pliku z tłumaczeniem, z którego będzie korzystała nasza aplikacja.
Okno programu - tłumaczenie
Okno programu - tłumaczenie

Konfiguracja

Pora, by użyć naszego tłumaczenia. Wg ustawionej ścieżki w kodzie (u nas 'share/locale') musimy utworzyć odpowiednie foldery obok naszego programu. Pierwsze folder share, w nim locale. W katalogu locale tworzymy katalogi odpowiadające językom, czyli dla języka polskiego: pl, angielskiego: en, itd. Pełną listę znajdziesz na stronie w3schools, przy czym dla j.angielskiego nie musimy tworzyć tłumaczenia, gdyż wszystkie teksty zostały przez nas napisane w tymże języku. Utwórzmy więc katalog 'pl' i jeśli jak ja utworzyłeś pakiet dla języka niemieckiego stwórz folder 'de'. W każdym folderze odpowiadającemu danemu językowi utwórz katalog o nazwie 'LC_MESSAGES'. Następnie przejdź do folderu, gdzie zapisałeś pakiet i zmień nazwę pliku z rozszerzeniem .mo na nazwę pakietu, czyli 'foo.mo'. Skopiuj plik ze zmienioną nazwą do katalogu 'LC_MESSAGES'.

Jeśli wszystko poprawnie wykonałeś, po uruchomieniu powinna się pokazać aplikacja w polskiej wersji językowej (oczywiście tylko wtedy, gdy język systemu jest ustawiony na pl).
Spolszczony program
Spolszczony program

Podsumowanie

Jak można się domyślić, internacjonalizacja programów jest bardzo przydatna w tworzeniu aplikacji. Tłumacząc program zyskujesz dodatkowe grono użytkowników, dla których jedna wersja językowa jest niewystarczająca, więc takie działanie jest opłacalne :)
Poprzedni dokument Następny dokument
GtkProgressBar Kurs Irrlicht, C++