|
Ci, którzy zaczynają programować w Qt będą
zaskoczeni widokiem znaków zapytania, jakie pojawiły się
w napisanych przez nich aplikacjach. Załóżmy, że w
naszym komputerze jest zainstalowany Linux (dowolna dystrybucja),
KDE 2.*, Qt 2.* i pakiet kde-i18n-pl, dzięki któremu KDE
jest spolonizowane. Poniżej umieszczono kod żródłowy programu
pr1 :
1 #include <qapplication.h>
2 #include <qlabel.h>
3
4 int main( int argc, char** argv )
5 {
6 QApplication app( argc, argv ) ;
7 QLabel* l = new QLabel( "Gżegżółka", 0 ) ;
8 l->show() ;
9 app.setMainWidget( l ) ;
10 return app.exec() ;
11 }
Kompilujemy go :
g++ -o pr1 -I$QTDIR/include -L$QTDIR/lib -lqt pr1.cpp
Po pomyślnym skompilowaniu, uruchamiamy program :
W tekście programu użyto polskich liter ale po jego
skompilowaniu i uruchomieniu pojawiły się znaki zapytania.
W bibliotece Qt (począwszy od jej wersji 2.0) obiekty klasy
QString przechowują napisy kodowane metodą Unicode, gdzie
każdy znak jest reprezentowany przez "dwubajtową" liczbę. W
takim obiekcie przechowywana jest także długość tego napisu.
Widgety często wyświetlają napisy, które są im przekazywane
jako obiekty QString. Na przykład deklaracja konstruktora
widgetu QLabel wygląda następująco:
QLabel( const QString & text, QWidget * parent,
const char * name=0, WFlags f=0 )
W wierszu nr 7 wywołuje się konstruktor klasy QLabel i jego pierwszym
argumentem jest obiekt typu char*. QLabel nie ma konstruktora,
który jako argument może przyjąć zmienną typu char*. Aby
wywołanie konstruktora się powiodło, kompilator musi dokonać
niejawnej konwersji typu. W tym celu tworzy obiekt chwilowy
QString a używa do tego następującego konstruktora
konwertującego:
QString( const char * str )
Cytat z dokumentacji Qt:
...This is a cast constructor, but it is perfectly safe:
converting a Latin1 const char* to QString preserves all
the information...
Jest to moment, w którym napis jest uszkadzany bo zakłada
się, że jest on kodowany w standardzie ISO 8859-1 (Latin1),
a faktycznie jest kodowany metodą Latin2 (ISO 8859-2).
Dekodowanie jest poprawne w przypadku znaków G, e, g, ó, k, a.
Ich kody, w ISO8859-1 i w ISO8859-2, są takie same. Kod litery
"ż" z ISO 8859-2 reprezentuje, w ISO 8859-1, znak o innym
wyglądzie. Podobnie jest ze znakiem "ł".
Przy uruchamianiu programu napisy są ponownie kodowane ale tym
razem z Unicode do standardu ISO 8859-2 (zgodnie z wartością
przechowywaną w zmiennej środowiska LANG). Niestety, w zbiorze
znaków, kodowanych metodą ISO 8859-2, nie ma znaków (179 i 191)
kodowanych metodą ISO 8859-1. W takim przypadku, w miejsce nie
znalezionych liter, Qt - standardowo - wstawia znak zapytania.
Aby program poprawnie wyświetlał polskie litery, należy
go nieco zmodyfikować:
1 #include <qapplication.h>
2 #include <qlabel.h>
3 #include <qstring.h>
4
5 int main( int argc, char** argv )
6 {
7 QApplication app( argc, argv ) ;
8 QString str = QString::fromLocal8Bit( "Gżegżółka" ) ;
9 QLabel* l = new QLabel( str, 0 ) ;
10 l->show() ;
11 app.setMainWidget( l ) ;
12 return app.exec() ;
13 }
Dodano nowy wiersz o numerze 8, w którym wywołuje się statyczną
metodę klasy QString, poprawnie dekodującą napis z
ISO 8859-2 do Unicode. Kodowanie napisu zostanie określone
na podstawie zmiennej środowiska LANG. Metoda fromLocal8Bit
dokonuje konwersji kodowania napisów z tradycyjnego
8-bitowego do kodowania Unicode.
Po skompilowaniu drugiego programu o nazwie pr2 i uruchomieniu,
otrzymuje się:
Jak widać problem został rozwiązany ale, mimo wszystko, nie
jest to rozwiązanie optymalne. Zmiana napisu wyświetlanego w
widgecie QLabel wymaga ponownej kompilacji programu. Ponowna
kompilacja będzie również potrzebna, gdy z naszego programu
zechcą skorzystać użytkownicy posługujący się innym językiem niż
polski. Przy pisaniu programów powinno przyjąć się zasadę, że w
tekście programu, napisy są w języku angielskim a ich tłumaczenia
znajdują się w oddzielnym pliku po. Qt ma specjalną klasę
zajmująca się tłumaczeniem napisów. Odpowiednikiem i18n jest
(w Qt) tr (ang.translate) - statyczna metoda w klasie QObject,
którą można użyć tak jak poniżej :
QLabel* l = new QLabel( QObject::tr("This is an english text"), 0 ) ;
Producent biblioteki Qt oferuje specjalne narzędzia do wyszukiwania
,w programie żródłowym, napisów przeznaczonych do tłumaczenia,
zamieniający plik .*po w plik *.mo, itd. - findtr, msg2qm,
mergetr, Linquist. Odpowiednio przygotowany plik wczytuje się do
obiektu klasy QTranslator (za pomocą metody load). Taki
obiekt należy jeszcze zarejestrować:
QApplication::installTranslator. Od tego momentu, aplikacja
powinna pokazywać przetłumaczone napisy.
Autor: Jerzy Skalski
Data 21.03.2001
[ DO GÓRY ]
|
|