哇,配置变得更长更吓人了,其实核心内容一共只有这几行:
set(TS_FILES ${CMAKE_SOURCE_DIR}/lang/zh_CN.ts ${CMAKE_SOURCE_DIR}/lang/ja_JP.ts) find_package(Qt${QT_VERSION} COMPONENTS ${REQUIRED_LIBS} LinguistTools REQUIRED) qt5_create_translation(QM_FILES ${CMAKE_CURRENT_SOURCE_DIR} ${TS_FILES}) add_executable(${PROJECT_NAME} main.cpp ${TS_FILES} ${QM_FILES})第一行很好理解,把我们的需要的ts文件的名字先设置到变量里。
接着我们引入Qt5::LinguistTools,这不是c++库,只是一个帮助生成ts文件和qm文件的cmake模块,所以不能链接到程序里。
最后一行也很简单,把ts文件加入编译程序的依赖项目里,一旦发生改变就重新构建我们的程序。
关键在于qt5_create_translation这里,这个函数会帮我们创建ts文件,如果ts文件已经存在就会更新ts文件把新添加的翻译追加进去;
到这步还没结束,在更新完ts文件后它会检查ts文件中是否有有效的翻译信息,如果有就在cmake的编译目录下生成和ts文件同名的qm文件。
中间的${CMAKE_CURRENT_SOURCE_DIR}就是指定从哪个目录下的源文件里获得需要翻译的文本的。
注意,如果qm文件最终没被用到的话,那么实际上不会被生成。为了能生成qm文件所以我们把它加入了依赖,还有更好的办法,后面介绍。
在Qt 6中我们只需要把函数名改成qt_create_translation就行了。
如果你想自己创建和更新ts文件,只需要把函数换成qt5_add_translation,它会自动根据ts文件生成qm文件,不过要是没有ts文件存在他就会报错。在Qt 6中它的名字会变为qt_add_translation。
上述的工作会在make的时候进行,比如这样:
添加翻译添加翻译没什么好讲的,你可以直接编辑ts文件,因为它是xml格式的,编辑起来还是很容易的。
不过有时候翻译需要参考文本和代码的上下文,这时候就需要用到Qt Linguist了:
具体的使用细节不再赘述,你可以参考园内和网上的其他优质文章。
编译运行后你就会在构建目录看到两个qm文件,这时候我们的程序还没有完成国际化支持,在代码中我们需要使用这些qm文件:
#include <QLocale> #include <QTranslator> int main() { QApplication a(argc, argv); QTranslator trans; if (trans.load("./" + QLocale().name() + ".qm")) { QCoreApplication::installTranslator(&trans); } ... return a.exec(); }我们用QTranslator加载本地的qm文件,QLocale的name方法正好可以返回诸如“ja_JP”的名字。
我的系统默认设置是日语,因此运行程序会看到这样的界面:
如果你的环境是中文的,那么显示的界面也是中文的,这就是Qt的i18n国际化支持。
将多语言资源绑定进程序到上一节结束我们其实就把i18n讲完了,你完全可以打包程序的时候把qm文件和程序放在一起,安装的时候也放在同一目录。
但这种方案还是有些缺点的:
如果支持的语言比较多,那么就会有大量的小文件需要处理,难免会出错;
需要把qm这种无关的文件放进编译依赖里
对于有代码洁癖的我来说第二点尤其忍不了,但是如果不用这些qm文件的话最终是不会生成他们的,怎么办呢?
其实还有办法,我们可以把这些qm文件都集成到qrc里。
首先在目录下创建一个translations.qrc文件:
<RCC> <qresource> <file>zh_CN.qm</file> <file>ja_JP.qm</file> </qresource> </RCC>