3.1 案例5 怎样实现国际化

本案例对应的源代码目录:src/chapter03/ks03_01。程序运行效果见图3-1。

图3-1 案例5运行效果

Qt提供的方案其实也很简单:显示文本时调用特定的翻译接口,然后需要开发者提供一个中英文对照的qm文件(二进制翻译文件),最后在程序启动时加载这个翻译文件。下面介绍具体步骤。

(1)在ui界面或代码中使用英文。

(2)在提供翻译的类中编写Q_OBJECT宏。

(3)在pro文件中添加TRANSLATIONS配置。

(4)使用lupdate命令,提取待翻译内容到ts文件。

(5)使用linguist(Qt语言家)在ts文件中添加中英文对照翻译,并导出qm文件。

(6)程序启动时加载qm文件。

现在分步骤进行详细介绍。

1.在UI文件或代码中使用英文

首先,在UI文件或者在编程时需要显示汉字的地方使用英文。在UI中显示文本时直接键入英文即可,在编程中显示文本时需要调用类的tr()接口进行翻译:

m_pLabel2->setText(tr("this is translated by source code"));

tr()接口是QObject类的接口,所以调用tr()的类要从QObject类派生。如果待翻译的文本所在的类不是QObject的派生类,那么请使用QObject类或它的派生类来调用tr()接口。

2.在提供翻译的类中编写Q_OBJECT宏

如果某个类中有文本需要翻译,那么除了要求该类从QObject类派生,还需要使用Q_OBJECT宏。假设类名为CDialog,就需要在CDialog类定义开头添加Q_OBJECT宏,如代码清单3-1所示

代码清单3-1

class CDialog : public QDialog {

    Q_OBJECT

    ...

};

如果不编写Q_OBJECT宏,那么在使用lupdate命令提取ts文件时将会报错。

ks03_01/dialog.cpp:7: Class 'CDialog' lacks Q_OBJECT macro Updating 'ks03_01.ts'...

        该错误提示的含义是:在更新ks03_01.ts文件时发现类CDialog缺少Q_OBJECT宏。

3.在pro文件中添加TRANSLATIONS配置

ts文件是Qt用来进行中英文翻译的文本文件,通过Qt的lupdate命令提取得到ts文件,然后由人工完成翻译。如果想得到ts文件,需要在ks03_01.pro中添加如下内容:

TRANSLATIONS = ks03_01.ts

ks03_01.ts是lupdate命令提取得到的ts文件名称。在配置TRANSLATIONS时也可以带文件路径。

TRANSLATIONS = $$TRAIN_SRC_PATH/translations/ks03_01.ts

这表示将lupdate命令提取的ts文件放到项目的src/translations目录下,文件名称为ks03_01.ts。

4.使用lupdate命令,提取待翻译内容到ts文件

完成pro文件中的TRANSLATIONS配置后,执行lupdate命令。

        lupdate ks03_01.pro

lupdate将读取pro文件中的TRANSLATIONS配置并读取源代码文件,将待翻译的文本提取到TRANSLATIONS配置项所指示的ts文件。如果未配置TRANSLATIONS将导致lupdate命令执行失败。

5.使用linguist在ts文件中添加中英文对照翻译,并导出qm文件

启动linguist,选择【文件】|【打开】菜单项打开ts文件。然后选择【上下文】中的类名,在【字符串】的列表框里选中某行源文,将翻译后的文本写在【Translation to 简体中文(中国)】下面的文本框内(见图3-2)。

图3-2 Qt语言家界面

        注意:标点符号也要一一翻译。

        完成一个源文的翻译后,单击源文前面的?(见图3-3)并将其改为√。

图3-3 未翻译的源文

完成全部翻译工作后,可以查看图3-3中【上下文】列表框的内容,检查是否还有未翻译的项目(未翻译的源文前面显示“?”,已翻译的显示√)。完成所有翻译后,将ts文件发布为二进制的qm文件。方法是选择【文件】|【另外发布为】菜单项,然后选择发布目录即可。比如,可以将qm文件发布到 $$(PRJROOT)/system/lang目录下。

6.程序启动时加载qm文件

在main()函数或其他合适的位置加载qm文件。

1)首先包含所需的头文件(见代码清单3-2)

代码清单3-2

#include <QApplication>

#include <QTranslator>  // 国际化

#include <QLibraryInfo> // 国际化

2)加载Qt自带的翻译文件

Qt自带的翻译文件用来实现Qt类中文本的翻译。如代码清单3-3所示,在标号①处得到本机的语言环境,在标号②处构建QTranslator对象,然后在标号③处安装翻译文件。标号③处处调用了QTranslator的load()接口,该接口的参数1用来描述翻译文件名,参数2用来描述翻译文件所在目录。

代码清单3-3

// 安装qt自带的中文翻译

const QString localSysName = QLocale::system().name();// 获取本机系统的语言环境    ①

QScopedPointer<QTranslator> qtTranslator(new QTranslator(QCoreApplication::instance()));                                   

if (qtTranslator->load(QStringLiteral("qt_") + localSysName, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))                           

    QCoreApplication::installTranslator(qtTranslator.take());

}

Qt的翻译文件并未把所有英文都翻译成中文(比如从Designer中拖出的QDialogButtonBox中的OK、Cancel按钮上的文本),开发者需要自己翻译这些英文。翻译Qt自带文本的方法是将这些文本按照ts文件的格式键入ts文件(见代码清单3-4)。<context>和</context>之间是QPlatformTheme类的翻译内容。name用来描述类名,每一组message用来描述一个源文和翻译的对照,其中source表示源文,translation表示翻译,location表示包含源文的代码行(可能不止一处)。完成人工翻译后,用linguist进行发布即可。

代码清单3-4

<context>

    <name>QPlatformTheme</name>

    <message>

        <location filename="../src/widgets/qdialogbuttonbox.cpp" line="+42"/>

        <location line="+18"/>

        <source>OK</source>

        <translation>确定</translation>

    </message>

    <message>

        <location line="+54"/>

        <source>Cancel</source>

        <translation>取消</translation>

    </message>

</context>

为什么QDialogButtonBox中的按钮没有被翻译成中文呢?这是因为在Qt的源代码里,为QDialogButtonBox的按钮进行翻译时,使用的是QPlatformTheme类。

QCoreApplication::translate ("QPlatformTheme" , "OK" );

这里的ts文件可以作为Qt的补丁。可以将上述ts文件的内容专门保存为一个公共的ts文件,然后把这个文件提供给各项目组使用。

3)加载项目的翻译文件

加载完Qt自带的翻译文件后,应加载项目的翻译文件,见代码清单3-5。

代码清单3-5

QString strPath = qgetenv("TRAINDEVHOME");  // 获取环境变量所指向的路径

strPath += "/system/lang";                  // $TRAINDEVHOME/system/lang/ks03_01.qm

QScopedPointer<QTranslator> gpTranslator(new QTranslator(QCoreApplication::instance()));

if (gpTranslator->load("ks03_01.qm", strPath)) {                                   

     QCoreApplication::installTranslator(gpTranslator.take());

}

国际化在Qt软件开发过程中是非常重要的组成部分。即使目前没有计划将产品推向国际市场,软件开发者也应该养成使用国际化进行编程的习惯。因为一旦将来需要将产品推向国际市场时,无须对源代码做任何修改就能马上推出产品,这会减少很多不必要的工作量。

----------------------------------------------------------------------------------------------------------------------------------------------

《Qt 5/PyQt 5实战指南》目录

posted @ 2019-09-02 22:18  女儿叫老白  阅读(195)  评论(0编辑  收藏  举报