Qt Jambi4.4文档翻译:使用Qt进行国际化,Internationalization with Qt
原文:http://doc.trolltech.com/qtjambi-4.4/html/com/trolltech/qt/qtjambi-i18n.html
(最新版英文文档可在这里找到: http://doc.qt.digia.com/qtjambi-4.5.2_01/com/trolltech/qt/qtjambi-i18n.html )
关于Qt jambi 对国际化和多语言的支持的信息。对一个程序进行国际化就是让这个程序可被与作者所在的国家不同的人使用的过程。
在某些情况下,国际化是很简单的,例如,要把一个美国的程序拿去给澳大利亚的或者英国的用户使用,可能只需要做一些拼写上的修改。但是要把一个美国程序拿去给一个日本鬼子用,或者把一个韩国程序拿去给一个德国佬用,就要求那个软件不止是使用不同的语言,还要使用不同的输入技术、字符编码和显示习惯。
Qt Jambi努力让开发者可以进行无痛的国际化。Qt Jambi 里面全部的输入部件和文字绘制方法都为所有受支持的语言提供内建的支持。内建的字体引擎可以正确并且漂亮地渲染出那些同时包含从多种不同的书写系统中弄出来的字符的文字。
Qt支持现在使用的大部分语言,具体地是:
•.•.所有的东亚语言(汉语、日语和韩语)
•.•.所有的西方语言(拉丁字母)
•.•.阿拉伯语
•.•.西里尔语(俄罗斯、乌克兰等等)
•.•.希腊语
•.•.以色列语
•.•.泰语和老挝语
•.•.Unicode 4.0 中不需要特殊处理的全部字符
在Windows、有FontConfig(客户端字体支持)的Unix/X11和用于嵌入式Linux 的Qt上,还支持以下语言:
•.•.孟加拉语
•.•.梵文
•.•.迪维希语 (马尔代夫语)
•.•.古吉拉特语
•.•.古尔穆希语
•.•.埃纳德语
•.•.高棉語
•.•.馬拉雅拉姆語
•.•.缅甸语
•.•.叙利亚语
•.•.坦米爾語
•.•.泰卢固语
•.•.西藏語
这些书写系统中有很多是有特殊习惯的:
•.•.特殊的换行行为。某些亚洲语言在书写的时候字与字之间没有空格。换行可能发生在任何一个字符之后(有例外),例如汉语、日语和韩语;也可能发生在逻辑词之后,例如泰语。
•.•.双向书写。阿拉伯语和以色列語是从右向左书写的,除咯数字和嵌入到其中的英语文字之外,那些东西是从左向右书写的。准确的行为是在Unicode 9号技术附件(Unicode Technical Annex #9)里定义的。
•.•.非空格或者区别符(欧洲语言中的重音或者元音标记)。某些语言,例如越南语,广泛地使用这些标记,某些字符可有多于一个标记,以澄清它的发音。
•.•.连字。在特定的上下文中,某些字母被一个点号代替,以形成一个连字。常见的例子就是美国和欧洲的书中使用排版的fl 和fi 连字。
Qt Jambi努力照顾到上面所列出的全部特性。只要你使用Qt Jambi 的输入部件(例如QLineEdit、QTextEdit和派生的类)和Qt Jambi 的显示部件(例如QLabel),那么你通常不用担心这些特性。
对这些书写系统的支持对于程序猿来说是透明的,是完全封装在Qt Jambi的文字引擎里的。这意味着,你不需要了解一个特定语言中的书写系统的任何东西,除咯以下小问题以外:
•.•.QPainter::drawText(int x, int y, const QString &str)在绘制的时候一直会将字符串的左边界放置到x、y 参数指定的位置。这就会一直生成左对齐的字符串。阿拉伯语和以色列语的程序中字符串通常是右对齐的,所以对于这些语言就使用那个以 QRect 为参数的drawText(),因为这样就能够根据语言的特性来对齐咯。
•.•.当你在编写你自己的文字输入控件时,使用QFontMetrics::charWidth()来确定一个字符串中的字符的宽度。在某些语言(例如阿拉伯语或者来自印度次大陆的语言)中,一个字符的宽度和开头是依据周围的字符而改变的。编写输入控件通常需求对它所要被用于其中的语言的文字系统有一定的了解。通常最简单的办法是子类化QLineEdit 或者QTextEdit。
下面的一些小节中有一些关于Qt Jambi 的国际化(i18n)支持的状态的信息。另外可参见Qt语言家手 册。
使用Qt Jambi 来编写跨平台的国际化软件是一个渐近的过程。你的软件可在以下阶段变成国际化的:
每当你的程序使用那些会显示到用户面前的"引号中的文字"时,确保它被QCoreApplication::translate()函数处理。实际上,为了实现这一点,只需要使用QtJambiObject::tr()。例如:
public LoginWidget()
{
QLabel abel = new QLabel(tr( "Password:" ));
...
}
这将覆盖到你所写出来让用户看的字符串中的99%。
如果引用的文字不在一个QtJambiObject 子类的成员函数里,那么就直接使用QCoreApplication::translate()函数:
void some_static_function()
{
QLabel abel = new QLabel(QApplication.instance().translate( "LoginWidget" , "Password:" ));
}
像Ctrl+Q 或者Alt+F 这样的快捷键也需要翻译。如果你在你的程序中将“退出”("quit")的快捷键硬编码为Qt::CTRL + Qt::Key_Q,那么翻译器将无法改写它们。正确的用法是
exitAct = new QAction(tr("E&xit"), this);
exitAct.setShortcut(tr("Ctrl+Q", "Quit"));
一旦你在一个程序中使用咯tr(),你就可以开始生成你的程序中那些用户可见的文字的翻译咯。
Qt语言家手册提供咯关于Qt Jambi 的翻译工具Qt语言家(Linguist)、lupdate 和lrelease 的详细信息。
对一个Qt Jambi 程序的翻译有3个步骤:
1.1.运行lupdate来从这个Qt Jambi 程序的Java 源代码中提取出文字,将生成一个用于翻译程序的消息文件(一个.ts文件)。这个工具识别出上面所描述的tr()结构,并且生成.ts文件(通常是每种语言一个)。
2.2.使用Qt语言家来为这个.ts文件中的源文字提供翻译。由于.ts文件是XML 格式的,所以你可以手动修改它们。
3.3.运行lrelease以从这个.ts文件中获取一个只适合于最终使用的轻量级的消息文件(一个.qm文件)。把.ts文件当成“源文件”,把.qm文件当成“目标文件”。翻译者编辑那些.ts文件,但是你的程序的用户只需要那些.qm文件。这两种文件都是与平台和地域无关的。
典型地,每当你发布你的程序时,你就会重复这些步骤。lupdate 工具会尽量重用以前的版本中的翻译内容。
在你的程序中,你必须使用QTranslator::load()来将适合于你的用户的语言的翻译文件载入到程序中,再使用QCoreApplication::installTranslator()来安装它们。
linguist、lupdate和lrelease都会安装到Qt Jambi 所安装到的基准目录中的bin 子目录里。在Qt语言家里面点击帮助|手册(Help|Manual)以访问用户手册;它包含咯一个教程,可带你上路。Qt自己也包含咯400多个字符串,它们也需要翻译为你将要使用的目标语言。你可以在$QTDIR/translations目录下找到针对法语、德语和简体中文的翻译文件,以及一个用来翻译为其它语言的模板。(这个目录中也包含咯一些附加的未受支持的翻译文件,它们也可能有用。)
典型地,你的程序的main()函数会是这样的:
public static void main(String args[])
{
QApplication.initialize(args);
QTranslator qtTranslator = new QTranslator();
qtTranslator.load( "classpath:/translations_directory/qt_" + QLocale.system().name() + ".qm" );
QApplication.instance().installTranslator(tTranslator);
QTranslator myappTranslator = new QTranslator();
myappTranslator.load( "classpath:/translations_directory/myapp_" + QLocale.system().name() + ".qm" );
QApplication.instance().installTranslator(myappTranslator);
...
QApplication.exec();
}
本地化就是适应本地的习惯的过程,例如,采用本地的习惯格式来表示日期时间。这种本地化过程可以使用适当的tr()字符串来完成。
void setTime(QTime ime)
{
if (tr( "AMPM" ) == "AMPM" ) {
// 12小时 制的时钟
} else {
// 24小时 制的时钟
}
}
在这个例子里,对于美国人,我们会将"AMPM"的翻译按原样保留,因此就会使用12小时的时钟分支;但是在欧洲勒,我们会把这个东西翻译成别的东西,这样的话,在代码里面就会进入24小时的时钟分支。
对于本地化的数字,使用QLocale 类。
不建议对图片进行本地化。选择适合于所有语言的清晰的图标,而不要依赖本地的双关语或者隐喻。唯一的例外是那些用来显示向左或者向右的箭头的图片,针对阿拉伯语和以色列语,可能需要将这些图片翻转。
某些程序,例如Qt 语言家,必须在它们还在运行的时候支持用户的语言设置的变化。要让部件知道那些安装咯的QTranslator的变化,就重载那个部件的changeEvent()函数,检查当前事件是不是一个LanguageChange 事件,并且像通常那样使用tr()函数来更新部件显示的文字。例如:
void changeEvent(QEvent vent)
{
if (e.type() == QEvent.Type.LanguageChange) {
titleLabel.setText(tr( "Document Title" ));
...
okPushButton.setText(tr( "K" ));
} else
QWidget.changeEvent(event);
}
所有其它的事件都应当通过调用这个函数的默认实现来继续传递下去。
已安装的翻译器的列表可以依据一个LocaleChange 事件来发生变化,或者程序可以提供一个用户界面以让用户改变程序的当前语言。
QWidget 子类的默认事件处理器会响应QEvent::LanguageChange 事件,并且在必要的时候调用这个函数;其它的程序组件也可以通过向部件发送LanguageChange 事件来强制让它们更新自己。
康师傅
眼镜蛇导弹
Your opinionsHxLauncher: Launch Android applications by voice commands