PyQt4和Qt带有一组强大 的工具,可用来将程序翻译 成本地语言。参考 Qt 文档 中的Qt 语言家手册以了解完 整 细节。
将一个程序国际化的过程包含以下步骤 。
•.针对程序要翻译的每种目标语言,程序 猿使用 pylupdate4 来创建或更新一个 .ts 翻译文件。 .ts 文件 是一个XML 文件,其中包含 的是 要翻译的字符串及对应 的翻译结果。 在开发过程中, pylupdate4 可被运行多次, 以便更新 .ts 文件, 使之包含最新的 待翻译 字符串。
•.翻译者使用Qt 语言 家来向 .ts 文件中填入各个字符 串的 翻译结果。
•.然后,负责发布程序的人员使用Qt 的 lrelease 工具来将 .ts 文件转换成 .qm 文件。 .qm 是经过压缩的二进制文件,包含 与 .ts 等价 的 内容 , 是 专门由程序本身来使用的。如果程序 没有找到对应的 .qm 文件,或者某个字符 串还没有被翻译,则 会使用 源代码中输入的字符串来代替。
•.负责发布程序的人员还可以 使用 pyrcc4 来 将 .qm 文件与程序 中的图标等资源 一起嵌入一个Python 模块中。 这将使得程序的打包 和发布工作更容易。
pylupdate4 是PyQt4中针对Qt的 lupdate 工具提供的等价工具,用法也是一样的。 它会读取一个Qt .pro 项目文件, 从中得知 有哪些Python 源文件和Qt 设计师界面文件,并从那些文件中提取 出 待翻译的字符串。 .pro 还指定了 要由 pylupdate4 更新(或在必要情况下创建)并且随后 会被Qt 语言家使用 的 .ts 翻译文件 。
pylupdate4只有在妳的Qt 中带有XML 模块 的情况下才会出现。
Qt通过QTranslator 类、 QCoreApplication::translate() 方法、 QObject::tr() 方法和 QObject::trUtf8() 方法来实现 国际化支持。通常 会使用 tr() 方法来获取 某条消息的正确 的翻译结果。翻译过程 中会使用一种消息上下文,来允许相同 的消息被翻译成不同的结果。 tr()实际上是由 moc 生成的, 它会使用硬编码的 类名作为上下文。 另一方面, QApplication::translate() 允许程序 猿显式地 指 明上下文。
遗憾的是,Qt 用了这样一种方式来实现 tr() ( 和 trUtf8() )函数,导致PyQt4 无法一模一样 地模仿它的行为。 在PyQt4 中, tr() (和 trUtf8())使用当前实例的类名作为上下文。由此产生 一个关键的区别,以及潜在的问题根源 : 上下文在PyQt4 中是动态确定的,而在Qt 中是硬编码的。 换句话说, 某条翻译信息的上下文 可能会因为该实例的类继承关系 而改变。例如:
在上面的示例中, 该条消息在两个函数中是按照不同的上下文翻译的: a.hello() 中是使用 A 作为上下文; b.hello() 中是使用 B 作为上下文。 而在等价的C++代码中, 上下文一直会是 A 。
对于这一点,PyQt4 在目前的处理方式不太令人满意,因此未来可能 会有变动。建议优先考虑使用 QCoreApplication.translate() ,而不是使用 tr() ( 和 trUtf8() )。 这 种方法 可以确保 在当前和未来的PyQt4 版本 中正确工作,并且更容易地 在Python 和C++代码中共用翻译文件。 以下是以 QCoreApplication.translate() 方式实现 的 A 类:
HxLauncher: Launch Android applications by voice commands