1. 概述
Redis Desktop Manager(RedisDesktopManager,RDM)是一个快速、简单、支持跨平台的 Redis 桌面管理工具,基于 Qt 5 开发,支持通过 SSH Tunnel 连接。
– 开源中国上面对项目的介绍
RedisDesktopManager
是一款优秀的 Redis
客户端。最初是作为开源项目发布的,官方也会发布编译好的版本。后来,作者做了一些商业化处理,上架了App Store
,从此不再发布编译后的版本,也在开源版本中阉割掉了 SSH Tunnel
功能。有鉴于此,网上有很多人写教程来说明如何从源码构建一个发行版本,但是目前见到的教程多多少少都有一些问题。最近花了一些时间尝试完善整个编译过程,目前进展不错。以后会陆续说明编译过程中碰到的问题以及对应的解决办法。
今天首先来说一下国际化的问题。
目前网上流行的 RedisDesktopManager
编译方法都没有对国际化文件进行处理,所以编译后的版本没有国际化功能,界面只显示英文,语言切换功能无效。经过对相关源码的分析,终于找到了正确的编译处理方法,现在可以完美切换语言。效果如图:
2. 源码分析
国际化有关的文件主要包括以下这些:
src/app/app.cpp
src/rdm.pro
src/resources/tr.qrc
src/resources/translations/*.ts
下面逐个分析。
2.1 app.cpp
app.cpp
是整个源码的起始,RedisDesktopManager
启动相关的源码基本都在该文件中。里面与国际化有关的主要是 installTranslator
这个函数。
1void Application::installTranslator() {
2 QSettings settings;
3 QString preferredLocale = settings.value("app/locale", "system").toString();
4
5 QString locale;
6
7 // 如果首选语言是system,则从系统中获取当前语言。在中文版Mac上,获取到的值是 zh-Hans-CN
8 // 这导致了在中文版Mac上如果选择system,界面显示的还是英文,而不是中文。详细内容请看下面的介绍
9 if (preferredLocale == "system") {
10 settings.setValue("app/locale", "system");
11 locale = QLocale::system().uiLanguages().first().replace("-", "_");
12
13 qDebug() << QLocale::system().uiLanguages();
14
15 if (locale.isEmpty() || locale == "C") locale = "en_US";
16
17 qDebug() << "Detected locale:" << locale;
18 } else {
19 locale = preferredLocale;
20 }
21
22 // 使用locale加载语言包。":/translations/rdm_"中的":"是QT中的用法,含义是从资源文件中加载
23 // 这个资源文件应该已经打包在可执行文件内部了。
24 QTranslator* translator = new QTranslator((QObject*)this);
25 if (translator->load(QString(":/translations/rdm_") + locale)) {
26 qDebug() << "Load translations file for locale:" << locale;
27 QCoreApplication::installTranslator(translator);
28 } else {
29 delete translator;
30 }
31}
2.2 rdm.pro
rdm.pro
文件是 RedisDesktopManager
项目的主工程文件,里面定义了整个项目的结构。其中也定义了国际化相关的内容,主要内容节选如下:
1# 此处首先判断是否存在rdm.qm这个文件,如果存在,则添加tr.qrc文件为资源文件
2exists( $$PWD/resources/translations/rdm.qm ) {
3 message("Translations found")
4 RESOURCES += $$PWD/resources/tr.qrc
5}
6
7# 这里指定了相关的语言包文件
8TRANSLATIONS = \
9 $$PWD/resources/translations/rdm.ts \
10 $$PWD/resources/translations/rdm_zh_CN.ts \
11 $$PWD/resources/translations/rdm_zh_TW.ts \
12 $$PWD/resources/translations/rdm_ru_RU.ts \
13 $$PWD/resources/translations/rdm_es_ES.ts \
14 $$PWD/resources/translations/rdm_ja_JP.ts \
2.3 tr.qrc
.qrc
文件是 QT
的资源定义文件,在编译过程中,资源文件会被打包到可执行文件中(个人猜测,尚未确定,但应该准确)。
1<RCC>
2 <qresource prefix="/">
3 <file>translations/rdm_zh_CN.qm</file>
4 <file>translations/rdm_zh_TW.qm</file>
5 <file>translations/rdm_ru_RU.qm</file>
6 <file>translations/rdm_es_ES.qm</file>
7 <file>translations/rdm_ja_JP.qm</file>
8 </qresource>
9</RCC>
可以看到在资源文件中定义了需要引入的qm文件列表。
2.4 translations
刚下载好的源码中 src/resources/translations
目录下面只有 .ts
文件,ts的含义是 translation source
,也就是翻译源码文件的意思。
3. 编译问题分析及解决
从 rdm.pro
文件中内容来看,编译时只有存在 src/resources/translations/rdm.qm
这个文件的时候才会把 tr.qrc
文件作为资源文件包含进来编译。而实际上下载的源码中目录 src/resources/translations
中只有 .ts
文件没有对应的 .qm
文件,这导致了编译过程中跳过了对语言包的处理,因此编译后的文件失去了国际化的功能。
解决办法就是在正式编译源码之前,首先将ts文件编译成qm文件。方法如下:
1cd src/resources/translations
2for file in `ls -1 *.ts`
3do
4 echo "Convert $file"
5 lconvert -i $file -o ${file%.*}.qm
6done
说明: lconvert
是QT带的一个工具,用于在语言包相关各种格式之间转换。需要首先安装qt。(brew install qt
)
4. 剩余问题
上面提到,如果语言选择system
,在中文版Mac上面是不能够正确显示中文的。其原因是从系统获得的语言名称是zh-Hans-CN
,由此期待的语言包文件名是:rdm_zh_Hans_CN.qm
,而实际语言包文件名是 rdm_zh_CN.qm
,显然无法找到。
解决办法是多复制一份文件即可:
1cd src/resources/translations
2for file in `ls -1 *.ts`
3do
4 echo "Convert $file"
5 lconvert -i $file -o ${file%.*}.qm
6done
7cp rdm_zh_CN.qm rdm_zh_Hans_CN.qm
同时修改tr.qrc
文件,添加这个qm文件:
1<RCC>
2 <qresource prefix="/">
3 <file>translations/rdm_zh_CN.qm</file>
4 <file>translations/rdm_zh_Hans_CN.qm</file>
5 <file>translations/rdm_zh_TW.qm</file>
6 <file>translations/rdm_ru_RU.qm</file>
7 <file>translations/rdm_es_ES.qm</file>
8 <file>translations/rdm_ja_JP.qm</file>
9 </qresource>
10</RCC>