最近的一个项目需要把系统从原先的英文版汉化。
为了完成这个工作,收集和学习了不少的资料。所以就自己整理资料留作记录吧。
在网上你会发现很多关于Qt显示中文出现乱码的现象:
于是你上网搜索解决方案,不外乎以下三个语句:
QTextCodec::setCodecForLocale(QTextCodec::codecForName("GB2312")); QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GB2312")); QTextCodec::setCodecForTr(QTextCodec::codecForName("GB2312"));
出现乱码的原因主要是因为Qt默认使用的编码方式是:Unicode;而windows中文系统的编码方式:GBK等;编码不一致所以出现乱码。
PS:用上面的方式解决中文化不是最优的方式;最好的方式是使用英文版本,通过国际化提供其中文版本。
言归正传,说说翻译问题.
Qt内部采用的全Unicode编码,这从根本上保证了多国语界面实现的正确性和便捷性。Qt本身提供的linguist工具,用来实现翻译过程十分方便。
Qt国际化的使用首先就需要用到:tr();出于国际化的需要,将需要在界面上显示的文字都用tr()包起来。推荐的使用方式:源码英文,然后提供英文到其他语言的翻译包。
首先,把需要翻译的文字使用tr()包裹起来;这点十分重要。因为Qt的翻译工具会把源码中所有的被tr()包裹起来的字符串提取出来,用于下一步的操作。
其次,需要在工程文件*.pro里面添加语句:;扩展名为ts的文件时翻译文件的源文件。包含了所有被tr包裹的字符串以及位置;
命名方式建议为:语言.ts例如:Chinese.ts、English.ts等。需要几个ts就添加几个。
TRANSLATIONS+= Chinese.ts\ English.ts再次,是使用lupdate工具编译提取出ts文件。使用方法如下:
windows下:运行中输入cmd,进入到命令行窗口,使用Cd语句进入到Qt安装目录下的bin文件夹;
然后输入:lupdate *.pro
*.pro包含pro文件的全路径。lupdate会解析*.pro文件,生成TRANSLATIONS中的 *.ts 文件
现在回在工程目录先看到*.ts文件。
Ubuntu下:打开终端,如果lupdate已经在bin目录下直接运行。如果没有则同windows下的操作相同。
最后,使用Qt自带的Linguist工具打开*.ts文件按照提示把每个需要翻译的字符串一一翻译,并且保存生成Release版本:即*.qm文件
*.qm文件是我们最后需要的二进制文件。它取出了很多不需要的信息。体积比*.ts文件小很多。
以上步骤我们已经获得了需要的翻译文件:*.qm;接下来我们需要加载这个文件来实现翻译。
代码如下:
int main(int argc,char* argv[]) { QApplication app(arcg,argv); QTranslator translator; translator.load(“Chinese”); app.installTranslator(&translator); }这个方式就是启动程序时候直接加载翻译文件。
void QTest::SL_translate() { if(!isChinese) { isChinese =true; bool bRet =false; bRet= m_pTranslator->load("Chinese.qm","./translators/"); qApp->installTranslator(m_pTranslator); } else { isChinese =false; qApp->removeTranslator(m_pTranslator); } reTranslatorUi(); }这是一个Qt的slots函数,这里m_pTranslator是一个QTranslator的类指针。isChinese是一个flags用于判断当前的语言。
使用这个函数可以进行动态加载。
注:
这里会有些人发现自己的函数调用了、加载翻译文件也成功了。可是界面的文字部分甚至于所有的字符转都没有转换到对应的语言,这是为什么呢?
其实细心的人已经发现我函数最后一行调用了函数:reTranslatorUi();
加载完翻译文件后,还需要一个步骤(非必须的);那就是重新加载tr包裹的字符串。
如果你的界面是由designer设计的那么你会发现那里有个函数:retranslateUi();加载翻译文件时候程序会自动调用这些语句以实现语言转换。
可是如果你界面的代码是自己使用语言手写的,而非designer设计器制作的,那么我们需要手动的编写一个retranslateUi()函数来重新加载字符串以达到切换语言的目的。
例如:
void QTest::reTranslatorUi() { this->setWindowTitle(tr("Test Program")); m_pBtn->setText(tr("Translate")); g_Str[1]=QObject::tr("SongTi"); pNew->setText(g_Str[1]); }
这样我们的步骤就都结束了。
这里是一个简单的例子:Translate