baizy77的个人主页

http://www.qtcn.org/bbs/u/88608  [收藏] [复制]

baizy77

小白

  • 2

    关注

  • 8

    粉丝

  • 1

    访客

  • 等级:新手上路
  • 总积分:0
  • 男,1977-11-27

最后登录:2021-01-06

更多资料

日志

3.1 案例5 怎样实现国际化

2020-12-24 14:48


本案例对应的源代码目录: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(newQTranslator(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实战指南》目录

分类:Qr入门与提高|回复:0|浏览:382|全站可见|转载
 

Powered by phpwind v8.7 Certificate Copyright Time now is:05-02 11:58
©2005-2016 QTCN开发网 版权所有 Gzip disabled