Qt - 使用内置翻译

Posted

技术标签:

【中文标题】Qt - 使用内置翻译【英文标题】:Qt - Use builtin translations 【发布时间】:2017-04-26 15:35:04 【问题描述】:

我正在使用 Qt 并希望翻译 Qt 小部件显示的“本地”文本。例如,“本机显示的文本”指的是上下文菜单中显示的文本编辑(复制、粘贴、...)。

这是我已经完成的:

#include <QApplication>
#include <QDebug>
#include <QTranslator>

#include <QFile>

int main(int argc, char *argv[])

    QApplication a(argc, argv);

    QTranslator translator;
    if(translator.load("qt_fr.qm", QApplication::applicationDirPath())) 
        qDebug() << a.installTranslator(&translator);
    

    qDebug() << QFile::exists(QApplication::applicationDirPath() + "/qt_fr.qm"); // just to debug file existence

    // MainWindow w;      // not related to my question
    // w.showMaximized(); // neither is this

    return a.exec();

对于 Qt5.6.2 和 MinGW 用户,qt_fr.qm 文件位于 path_to_qt/Qt5.6.2/5.6/mingw49_32/translations。我将上述文件复制到正在运行的软件目录,但翻译器总是无法加载它。但是当我使用自己的 qm 文件(使用 Qt lupdate 和 lrelease 工具从 .ts 文件构建)时,qm 文件已正确加载和安装。

我有什么遗漏或做错了吗?

【问题讨论】:

Qt 将首先附加一个后缀(默认为.qm),所以我建议从文件名参数中删除它。请注意,文档也建议使用接受 QLocale 作为第一个参数的重载。例如,translator.load(QLocale::French, "qt", QApplication::applicationDirPath()) 确实你是对的:如果文件名没有添加扩展名,加载过程很简单。但是由于 Qt 在加载失败时会回溯并重试,因此添加 .qm 扩展名不应导致失败。我也尝试了使用 QLocale 的版本,但它仍然无法正常工作。欢迎任何其他建议。 此外,使用 QLocale 假定我们正在加载的 qm 文件与运行我们软件的操作系统上安装的语言相匹配。但是sometimes 我们可以选择英语同时是德语(例如)。当我使用自己的 .qm 文件(lupdate 和 lrelease)时,我上面提供的 sn-p 工作正常,但在加载 Qt 内置 .qm 文件时,加载过程失败。 我的评论只是“最佳实践”而不是解决方案(这就是为什么它是评论而不是答案的原因)。但它绝对允许使用操作系统不支持的语言环境——因此我使用QLocale::French(以及隐含的接受QLocale::Language 的构造函数)而不是简单的QLocale。至于解决这个问题,我有兴趣阅读一些实际的答案,并为自己学习更多关于 Qt 翻译的知识。 你绝对是对的。它甚至在文档中声明:我感到羞耻。无论如何,希望有人能够为我提供解决方案,因为似乎 Qt 内置 .qm 文件的部署方式与我自己创建的方式不同(使用 lupdate 和 lrelease)。然而我并没有使用各种版本的 Qt。 【参考方案1】:

我认为问题可能是您没有复制完整的消息目录。以下在 Debian 系统上对我有用,在其标准位置使用 QM 文件:

#include <QApplication>
#include <QDebug>
#include <QLocale>
#include <QTranslator>

int main(int argc, char *argv[])

    QApplication a(argc, argv);
    QTranslator translator;
    const QString dir = "/usr/share/qt5/translations";

    if (translator.load("qt_fr", dir)) 
        qDebug() << "first load succeeded:"
                 << "'Open' =>" << translator.translate("QShortcut", "Open");
    

    if (translator.load(QLocale::French, "qt", "_", dir)) 
        qDebug() << "second load succeeded:"
                 << "'Open' =>" << translator.translate("QShortcut", "Open");
    

输出是

first load succeeded: 'Open' => "Ouvrir"
second load succeeded: 'Open' => "Ouvrir"

(我从文件名中删除了.qm,因为 Qt 将首先尝试这样做,并且我还展示了如何从特定的语言环境对象组成文件名)。

如果我们使用lconvert -of ts /usr/share/qt5/translations/qt_fr.qm 检查qt_fr.qm 文件,我们可以看到它只是一个非常小的文件,它通过引用合并了其他文件:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="fr_FR">
<dependencies>
<dependency catalog="qtbase_fr"/>
<dependency catalog="qtscript_fr"/>
<dependency catalog="qtquick1_fr"/>
<dependency catalog="qtmultimedia_fr"/>
<dependency catalog="qtxmlpatterns_fr"/>
</dependencies>
</TS>

我认为您的症状最可能的原因是无法加载一个或多个依赖文件。您应该确保所有这些文件区域都在您复制 qt_fr.qm 到的同一位置 - 或者,如果您只需要“基本”翻译,只需复制 qtbase_fr.qm,并适当更改您的 translator.load() 调用。

【讨论】:

确实我没有复制依赖文件,这就是为什么翻译器总是无法加载 qm 文件。我现在也意识到,由于我只想翻译文本编辑上下文菜单,加载 qtbase_fr 完全适合我的需要,不需要依赖文件。非常感谢,如果可以的话,我会投票赞成 10 票。 :) 顺便说一句,你怎么知道 lconvert 工具?那就是我从未听说过它,我对 Qt 并不陌生,除非有人告诉我,否则我不知道任何魔术可以帮助我。 对不起,这里不是以英语为母语的人 LConvert 似乎不太为人所知——它只是在 Qt 文档中简要提及,并且没有附带手册页。我所知道的一切都是我使用lconvert -help 学到的。是的,我应该建议您可能只需要 qtbase 翻译,但您似乎在没有我帮助的情况下解决了这个问题! :-) 我对最后一段进行了一些编辑,以供未来的读者阅读。

以上是关于Qt - 使用内置翻译的主要内容,如果未能解决你的问题,请参考以下文章

Qt翻译文件(.ts)的使用

无论操作系统语言如何,如何翻译使用预构建的 Qt 安装程序框架创建的安装程序

qt中制作添加 .ts 翻译文件

qt中制作添加 .ts 翻译文件

Qt 国际化翻译

Qt