Qt/Embedded中文化介绍

Qt/Embedded中文化介绍

方案一
 
2 楼
环境配置:
Qt/Embedded 3.3.3 (其他版本应该大同小异)
|-----> 在宿主机上存放路径为:/opt/workspace/embedde/Qt/qte-3.3.3-target
|-----> 在目标机上存放路径为:/usr/lib/qt-3.3.3/
Qt/X11 3.3 (主要用其中的lupdate,lrelease和lingust工具)

步骤:
1)编写并编译应用程序,使用Qt/Embedded的i18n支持,让应用程序支持多种语言显示;
2)使用lupdate,lrelease和lingust工具,生成.ts和.qm等i18n需要的文件;
3)使用makeqpf工具生成中文字体文件;
4)设置locale,并应用指定字体运行应用程序。

Step 1:编写并编译应用程序,使用Qt/Embedded的i18n支持,让应用程序支持多种语言显示

代码: [复制到剪贴板]
  1. #include <qapplication.h>
  2. #include <qlabel.h>
  3.  
  4. /* if you do NOT want to use locale,
  5. * just comment the following line.
  6. */
  7. #include <qtextcodec.h>
  8.  
  9. int main (int argc, char * argv[])
  10. {
  11. QApplication app(argc, argv);
  12. QTranslator translator;
  13.  
  14. /* if you do NOT want to use the locale,
  15. * delete " + QTextCodec::locale()" in the next line and
  16. * replace with your specfic language file name.
  17. * For example:
  18. * translator.load(QString("lang_zh.qm"), qApp->applicationDirPath());
  19. */
  20.  
  21. translator.load(QString("lang_") + QTextCodec::locale(), qApp->applicationDirPath());
  22.  
  23. app.installTranslator(&translator);
  24.  
  25. QLabel * label = new QLabel(QObject::tr("Hello, World!"), 0);
  26.  
  27. app.setMainWidget(label);
  28.  
  29. label->show();
  30.  
  31. return app.exec();
  32. }

在上面的代码中,比较重要的有两处:

第一处在12-19行,为应用程序生成一个translator,使其支持多种语言。而重中之重则是translator.load()。它指明translator所要加载的.qm(后面步骤会说明.qm文件的生成方法)文件的位置。
如果你想使用系统的locale来决定translator所需要使用的语言文件,那么你就使用下面的代码:

代码: [复制到剪贴板]
  1. translator.load(QString("lang_") + QTextCodec::locale(), qApp->applicationDirPath());

QTextCodec::locale()会根据系统环境变量LANG当前的值来决定加载的文件名称,例如当前LANG=zh,那么translator就会在应用程序的当前路径中寻找名为"lang_zh.qm"的文件,找到后将其内容加入内存中。
如果觉得麻烦不想设置locale,那么也可以直接指定语言文件的位置:

代码: [复制到剪贴板]
  1. translator.load(QString("lang_zh.qm"), qApp->applicationDirPath());

第二处在25行,生成QLabel时,将Label字符串用QObject::tr()括起来。这是为了同志translator,该字符串会用多种语言显示,而后面用到的lupdate等工具也是通过这个标志来搜索源文件需要翻译的字符串的。

好,编译生成应用程序:(大家编译上应该没Qt/Embedded及应用程序应该没有什么问题了,所以我在这里只列出步骤不详细说明了)

host# export QTDIR=/opt/workspace/embedded/Qt/qte-3.3.3-target/
host# qmake -project -o lang.pro
host# qmake -spec $QTDIR/mkspecs/qws/linux-arm-g++ -o Makefile
host# make



Step 2:使用lupdate,lrelease和lingust工具,生成.ts和.qm等i18n需要的文件;编写并编译应用程序,使用Qt/Embedded的i18n支持,让应用程序支持多种语言显示
在上一步中生成的lang.pro文件中加入TRANSLATIONS的定义,内容如下:

代码: [复制到剪贴板]
  1. ######################################################################
  2. # Automatically generated by qmake (1.07a) Sun Nov 27 10:27:52 2005
  3. ######################################################################
  4.  
  5. TEMPLATE = app
  6. CONFIG -= moc
  7. INCLUDEPATH += .
  8.  
  9. # Input
  10. SOURCES += main.cpp
  11.  
  12. # Translation
  13. TRANSLATIONS += lang_zh.ts

最后一行就是TRANSLATIONS的定义,lupdate会根据这个定义将当前目录中所有源文件中的需要翻译的字符串提取出来放在main_zh.ts文件中。我们执行:

host# lupdate -verbose lang.pro
Updating 'lang_zh.ts'...
0 known, 1 new and 0 obsoleted messages
host#


此时目录中会生成一个lang_zh.ts的XML格式的文件,内容如下:

代码: [复制到剪贴板]
  1. <!DOCTYPE TS><TS>
  2. <context>
  3. <name>QObject</name>
  4. <message>
  5. <source>Hello, World!</source>
  6. <translation type="unfinished"></translation>
  7. </message>
  8. </context>
  9. </TS>。

我们可以看到Hello, World!出现在该文件中。下面我们要做的就是翻译,你可以用lingust,也可以自己翻译。
Linugst是Qt自带的翻译工具,一般RedHat 9.0安装Qt后都有该工具,在QT/Embedded源码目录的tools中也有该工具。使用方法很简单,我就不详细说明了。(如果不会用的话,你还是会火星去吧,地球不适合你!)
自己翻译就是在lang_zh.ts文件中直接修改,针对"Hello, World!",我们只要在相应的<translation></translation>中加入翻译的内容即可。
不管你用什么方法翻译,翻译后的文件内容应该如下:

代码: [复制到剪贴板]
  1. <!DOCTYPE TS><TS>
  2. <context>
  3. <name>QObject</name>
  4. <message>
  5. <source>Hello, World!</source>
  6. <translation type="unfinished">你好,世界!</translation>
  7. </message>
  8. </context>
  9. </TS>

OK,执行lrelease,生成相应.qm文件:

host# lrelease -verbose lang.pro
Updating 'lang_zh.qm'...
0 finished, 1 unfinished and 0 untranslated messages
host#


OK,大功告成,赶紧运行一下应用程序:

target# export QTDIR=/usr/lib/qt-3.3.3
target# export QWS_MOUSE_PROTO=LinuxTP:/dev/h3600_ts
target# export QWS_KEYBOARD=Mx1AdsKeypad:/dev/i2c_keypad
target# ./lang -qws



“晕,怎么是方格!!!shit!”
(呵呵,你太心急了,后面还有两步没有做,正常情况下应该显示不了中文,如果显示中文了,赶紧去买彩票吧,说不定能种头奖!)




Step 3:使用makeqpf工具生成中文字体文件
默认情况下Qt/Embedded在lib/fonts目录下已经提供了一种可以显示中文的字体库,UniFont,其中包含以下几个文件:
unifont_160_50.qpf
unifont_160_50_t10.qpf
unifont_160_50_t15.qpf
unifont_160_50_t5.qpf
unifont.bdf
qpf文件时Qt/Embedded专用的一种适合嵌入式字体,是一种位图字体,每个文件只包含一种尺寸的字体,不能缩放,相应带来的好处就是占用的磁盘 空间很小,一般只有600K到1M。一般情况下我们使用这个unifont就可以显示中文了,效果很不错。当然如今什么都要个性化,如果你不喜欢这个字 体,我们下面就自己生成一个中文字体。
在Qt/Embedded的lib/fonts目录中有一个fontdir的配置文件,内容如下:

代码: [复制到剪贴板]
  1. ...
  2. # Unifont is available in source form from http://czyborra.com/unifont/
  3. unifont unifont.bdf BDF n 50 160 u
  4. ...

每一行是关于一种字体的设置,对应列的定义如下:
<字体名称> <字体文件名> <字体渲染类型> <是否斜体> <是否粗体> <尺寸> <字体标志> [尺寸列表]
其中,
<字体渲染类型>:可以为TTF,BDF,QPF三种类型;
<是否斜体>:y表示为斜体,n表示正常体;
<是否粗体>:50表示正常体,75表示粗体;
<标志>:a使用ASCII字符集,u使用unicode字符集,s使用锯齿平滑(anti-aliased);
<尺寸>:0,则系统从[尺寸列表]中提取可以转换的字体尺寸;

下面我们使用windows下的提供的一种TrueType的字体练练手,我们就以华文细黑字体为例(我个人比较喜欢华文细黑,在我的台式机上显示效果很不错,不过在嵌入系统上显示的一般):
将stxihei.ttf放到/usr/lib/qt-3.3.3/lib/fonts/目录中(注意这个是目标机的目录,不要混淆了),然后编辑该目录中的fontdir文件,在文件最后加入下面的内容:

代码: [复制到剪贴板]
  1. #Chinese Fonts
  2. stxihei stxihei.ttf FT n 50 140 su

(注意:字体标志一定要加上u,说明使用unicode字符集,不然显示出现“方块”什么的,不要说没提醒你!)
如果你想使用TrueType字体,那么这样的配置就OK了,可以跳过下面的内容直接进入最后一步。

下面我们将TTF字体转换成QPF字体。Qt/Embedded提供了一个十分方便的工具来完成这项工作makeqpf,该工具放在源码目录tools/makeqpf中。
makeqpf通过读取$QTDIR中的lib/fonts/fontdir来获取需要转换的字体信息,然后生成相应的QPF字体。
使用makeqpf,你可以直接运行:

target# makeqpf

然后点击你想转换的字体,转换成功之后,你会在屏幕上看见转后的字体的显示效果。
或者你可以运行:

target# makeqpf <font_name> [charset range](例如makeqpf stxihei 0-ff,4e00-fa29)

转换指定字体中指定范围内的字符字体。
我们以上述的“stxihei stxihei.ttf FT n 50 140 su”为例,通过在makeqpf中点击stxihei来生成一个华文细黑的QPF文件,文件名称为“stxihei_140_50.qpf”,再次修改 fontdir文件,注视掉原有的关于stxihei配置,加入新的字体信息:

代码: [复制到剪贴板]
  1. #Chinese Fonts
  2. #stxihei stxihei.ttf FT n 50 140 su
  3. stxihei stxihei_140_50.qpf QPF n 50 140 su

OK,现在基本的配置都完成了,赶紧运行一下应用程序:

target# export QTDIR=/usr/lib/qt-3.3.3
target# export QWS_MOUSE_PROTO=LinuxTP:/dev/h3600_ts
target# export QWS_KEYBOARD=Mx1AdsKeypad:/dev/i2c_keypad
target# ./lang -qws



“汗!怎么还是方格!!@#$%...”


Step 4:设置locale,并应用指定字体运行应用程序
如果你刚才在代码中使用QTextCodec::locale()来决定使用.qm文件,那么首先:

target# export LANG=zh

然后最后检查一下,在目标机上应该有以下内容:
1)$QTDIR/lib/fonts/stxihei_140_50.qpf(或者是stxihei.ttf);
2)$QTDIR/lib/fonts/fontdir中应该有以下的配置:
stxihei stxihei_140_50.qpf QPF n 50 140 su(或者stxihei stxihei.ttf FT n 50 140 su);
3)应用程序目录下应该有lang_zh.qm文件。
哈,激动人心的时刻到了,运行:

target# ./lang -qws -font stxihei

或者:

target# ./lang -qws -font unifont

在Qt/Embedded中每个QApplication应用程序启动时如果不加-font的参数,它会使用默认的字体“Helvetica”,所以除非你应用程序中指定了QApplication对象的字体,否则,就看“方块”吧。

“其实大多数人就差最后一步,结果被骗看完了整篇文章。嘿嘿,对此我深表遗憾”Qt/Embedded中文化介绍