Qt国际化(2)——实例
一个利用Qt实现国际化的小例子:界面非常简单,用一个下拉菜单来选择语言,然后下面有一个标签,上面的文字是著名的”Hello World”(或者它的翻译)。
代码如下:
tr()函数前一个参数是提取翻译串时用到的ID,后一个则是提供注释的作用,并且在取不到翻译串时注释串会被采用。比如语言设置为中文时,以TXT_HELLO_WORLD为ID的串在对应的.qm文件中找不到翻译后的字符串的话,就会采用后一个参数,即显示为英文。
改变语言的具体过程:
槽changeLang()中我们先从所选的菜单项中取得对应语言的值(即我们在18-20行中的第二个参数所加入”en”、”zh”和”la”),传给函数changeTr()去读取相应的.qm文件,然后刷新标签上的文字即可。而函数changeTr()则负责去读取对应的.qm文件,并调用installTranslator()方法来安装QTranslator对象。由于我们需要动态改变语言,所以如果已经安装了QTranslator对象的话,首先需要调用removeTranslator()移除原来的QTranslator对象,再安装新的,因此在44行我们定义了一个static的QTranslator对象以方便移除和重新安装。另外注意为简单起见我们将.qm文件的路径直接设定在当前路径下,命名分别为lang_en.qm, lang_zh.qm, lang_la.qm。
对于程序员来说,上面的这些工作基本已经足够,剩下的提取需要翻译的字符串并翻译然后生成.qm文件的工作一般有专门的工作组去负责,简介如下:
首先我们需要对qmake自动生成的langswitch.pro文件稍作修改,在后面加上TRANSLATIONS的定义,如下面的14-16行所示:
然后我们可以利用lupdate工具来提取需要翻译的字符串,运行命令及结果如下所示:
这时候我们得到了lang_en.ts,lang_la.ts和lang_zh.ts三个文件。由于它们都是xml格式的,我们可以直接用cat命令来查看它们的内容,比如:
可以看到ID为TXT_HELLO_WORLD的串此时尚未被翻译。那么接下来的工作就是利用linguist来翻译这几个.ts文件了。如果你的PATH设置正确的话,直接敲入linguist命令就可以启动它,然后打开需要翻译的.ts文件,就可以进行字符串的翻译了,:
翻译完一个串之后可以选择菜单”Translation->Done and Next”或者Ctrl加回车键将这个串设置为翻译完成,然后继续下一个(当然这个小例子中我们只有一个串需要翻译)。当所有的串都翻译完成后可以保存退出,这时可以来查看一下.ts文件的变化:
可以看到行<translation>Orbis, te saluto</translation>,表示这是翻译之后的结果。对于翻译成中文的情况是类似的。
在得到翻译之后的.ts文件后,最后的工作就是使将它们变为更紧凑的格式,即生成相应的.qm文件。这可以利用lrelease来完成:
至此所有的准备工作都已经做好了,可以编译运行,效果如下:
一般一个系统中对语言的切换应该采用广播事件而不是简单的采用发射信号的方式来处理,不过其他原理类似。
代码如下:
| 文件 | langswitch.rar |
| 大小 | 21KB |
| 下载 |
| 1 #ifndef LANGSWITCH_H 2 #define LANGSWITCH_H 3 4 #include <QWidget> 5 6 class QComboBox; 7 class QLabel; 8 9 class LangSwitch : public QWidget 10 { 11 Q_OBJECT 12 public: 13 LangSwitch(); 14 ~LangSwitch() {}; 15 16 private slots: 17 void changeLang(int index); 18 19 private: 20 void createScreen(); 21 void changeTr(const QString& langCode); 22 void refreshLabel(); 23 24 QComboBox* combo; 25 QLabel* label; 26 }; 27 28 #endif //LANGSWITCH_H |
在LangSwitch.h文件中定义了类LangSwitch,用来创建出上面的用户界面。其中24行和25行分别是我们在上面界面中可以看见的下拉菜单和标签,第17行定义的槽changeLang()用来响应下拉菜单中语言选项的改变,20行-22行定义的几个私有函数则用来协助创建界面和改变语言。
LangSwitch.cpp中的具体实现:
| 15 void LangSwitch::createScreen() 16 { 17 combo = new QComboBox; 18 combo->addItem("English", "en"); 19 combo->addItem("Chinese", "zh"); 20 combo->addItem("Latin", "la"); 21 22 label = new QLabel; 23 refreshLabel(); 24 25 QVBoxLayout* layout = new QVBoxLayout; 26 layout->addWidget(combo, 1); 27 layout->addWidget(label, 5); 28 29 setLayout(layout); 30 31 connect(combo, SIGNAL(currentIndexChanged(int)), 32 this, SLOT(changeLang(int))); 33 } |
createScreen()用来创建基本的界面。18行-20行我们将三个语言选项英语、中文和拉丁语加到了下拉菜单中,并设置三个选项的值分别为”en”、”zh”和”la”(这是ISO标准中语言的简写形式)。23行调用私有函数refreshLabel()设置标签的内容,实现如下:
| 61 void LangSwitch::refreshLabel() 62 { 63 label->setText(tr("TXT_HELLO_WORLD", "Hello World")); 64 } |
改变语言的具体过程:
| 35 void LangSwitch::changeLang(int index) 36 { 37 QString langCode = combo->itemData(index).toString(); 38 changeTr(langCode); 39 refreshLabel(); 40 } 41 42 void LangSwitch::changeTr(const QString& langCode) 43 { 44 static QTranslator* translator; 45 46 if (translator != NULL) 47 { 48 qApp->removeTranslator(translator); 49 delete translator; 50 translator = NULL; 51 } 52 53 translator = new QTranslator; 54 QString qmFilename = "lang_" + langCode; 55 if (translator->load(qmFilename)) 56 { 57 qApp->installTranslator(translator); 58 } 59 } |
对于程序员来说,上面的这些工作基本已经足够,剩下的提取需要翻译的字符串并翻译然后生成.qm文件的工作一般有专门的工作组去负责,简介如下:
首先我们需要对qmake自动生成的langswitch.pro文件稍作修改,在后面加上TRANSLATIONS的定义,如下面的14-16行所示:
| 1 ################################################################# 2 # Automatically generated by qmake (2.01a) Tue Mar 6 16:04:46 2007 3 ################################################################# 4 5 TEMPLATE = app 6 TARGET = 7 DEPENDPATH += . 8 INCLUDEPATH += . 9 10 # Input 11 HEADERS += LangSwitch.h 12 SOURCES += LangSwitch.cpp main.cpp 13 14 TRANSLATIONS = lang_en.ts \ 15 lang_zh.ts \ 16 lang_la.ts |
| $ lupdate langswitch.pro Updating 'lang_en.ts'... Found 1 source text (1 new and 0 already existing) Updating 'lang_la.ts'... Found 1 source text (1 new and 0 already existing) Updating 'lang_zh.ts'... Found 1 source text (1 new and 0 already existing) |
| $ cat lang_la.ts <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS><TS version="1.1"> <context> <name>LangSwitch</name> <message> <location filename="LangSwitch.cpp" line="63"/> <source>TXT_HELLO_WORLD</source> <comment>Hello World</comment> <translation type="unfinished"></translation> </message> </context> </TS> |
翻译完一个串之后可以选择菜单”Translation->Done and Next”或者Ctrl加回车键将这个串设置为翻译完成,然后继续下一个(当然这个小例子中我们只有一个串需要翻译)。当所有的串都翻译完成后可以保存退出,这时可以来查看一下.ts文件的变化:
| $ cat lang_la.ts <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS><TS version="1.1" language="en_US"> <context> <name>LangSwitch</name> <message> <location filename="LangSwitch.cpp" line="20"/> <source>TXT_HELLO_WORLD</source> <comment>Hello World</comment> <translation>Orbis, te saluto</translation> </message> </context> </TS> |
在得到翻译之后的.ts文件后,最后的工作就是使将它们变为更紧凑的格式,即生成相应的.qm文件。这可以利用lrelease来完成:
| $ lrelease langswitch.pro Updating 'lang_en.qm'... Generated 1 translation (1 finished and 0 unfinished) Updating 'lang_la.qm'... Generated 1 translation (1 finished and 0 unfinished) Updating 'lang_zh.qm'... Generated 1 translation (1 finished and 0 unfinished) |
![]() |
一般一个系统中对语言的切换应该采用广播事件而不是简单的采用发射信号的方式来处理,不过其他原理类似。



