c++ - 在 translations.qrc 文件中读取翻译器文件 .ts/.qm

标签 c++ qt qt-resource qtranslator

我正在尝试在我的 Qt 项目(Linux 系统上的 Qt 5.6)中导入翻译文件,但我无法上传翻译文件,因为 QTranslator::load 方法始终返回 false

我有以下“testTrl”项目结构:

在项目根目录下,我有“resources”文件夹,其中包括“qml.qrc”、“translations.qrc”和“translations”文件夹:

/resources/qml.qrc
/resources/translations.qrc
/resources/translations/testTrl_it.ts
/resources/translations/testTrl_it.qm
/resources/translations/testTrl_en.ts
/resources/translations/testTrl_en.qm
...

我已经通过“lrelease”和“lupdate”命令获得了“.ts”和“.qm”文件。

项目文件:

testTrl.pro 文件:

TEMPLATE = app

QT += qml quick core widgets
CONFIG += c++11

SOURCES += main.cpp

RESOURCES += $$PWD/resources/qml.qrc \
             $$PWD/resources/translations.qrc

TRANSLATIONS += $$PWD/resources/translations/testTrl_it.ts \
                $$PWD/resources/translations/testTrl_en.ts

# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =

# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

translations.qrc 文件:

<RCC>
    <qresource prefix="/translations" lang="it">
        <file alias="testTrl.qm">translations/testTrl_it.qm</file>
    </qresource>
    <qresource prefix="/translations" lang="en">
        <file alias="testTrl.qm">translations/testTrl_en.qm</file>
    </qresource>
</RCC>

main.cpp 文件:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QTranslator>
#include <QDebug>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QTranslator translator;

    const QString lang = "en";
    QLocale::setDefault(lang);

    bool isTrlsFileLoaded = translator.load(":/translations/testTrl.qm");

    if(!isTrlsFileLoaded) {
        qDebug() << "FILE NOT LOADED";
    }
    else {
        qDebug() << "FILE LOADED";
        qApp->installTranslator(&translator);
    }

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

“isFileTranslatorLoaded”始终为“false”。我该如何解决这个问题?

最佳答案

首先,您的 .qrc 文件写错了:第二个标签 <qresource>应该是 </qresource> , 最后一个 <RCC>应该是 </RCC> .

虽然你的源代码是部分的,但我猜你要找的那一行是

bool isFileTranslatorLoaded = translator->load(":/translations/translations/app_it.qm");

QTranslator::load 只能加载已编译的 (.qm) 文件。从资源中删除 .ts 文件(此外,这是一种安全措施,因为它们通常会暴露部分项目结构、源代码行等)。

一种不同的方法

作为建议,您可以通过在资源文件中设置语言来减少加载翻译时的关联代码。

<RCC>
  <qresource prefix="/translations">
    <file alias="app.qm">translations/app_en.qm</file>
  </qresource>
  <qresource prefix="/translations" lang="it">
    <file alias="app.qm">translations/app_it.qm</file>
  </qresource>
</RCC>

然后,您只需加载一个通用翻译器:

bool isFileTranslatorLoaded = translator->load(":/translations/app.qm");

Qt 将负责为当前语言环境使用适当的文件。它对于在设计时指定的其他资源特别有用,例如图像,或者只是为了减少代码困惑。

注意:看到 alias允许您删除双 translations/translations如果你愿意的话。

设置语言环境

如前所述,上述代码使用当前语言环境从资源中选择正确的文件。翻译加载器可能看起来像

bool loadTranslationsForLanguage(const QString& lang) {
  QLocale::setDefault(lang);

  std::unique_ptr<QTranslator> translator(new QTranslator());
  if (!translator->load(":/translations/app.qm")) return false;

  qApp->installTranslator(translator.release()); // possible memory-leak, see below

  return true;
}

关于在 this answer 中设置语言环境的更多信息.

更换翻译人员

如果您已经加载了翻译器,那么您将面临新的挑战,因为 Qt 将允许您安装新的翻译器,但会继续使用旧文件(在搜索翻译时,它会在第一个匹配项处停止)。

要实现语言更改,您必须跟踪已安装的所有翻译器,并在切换时将其删除。

std::unique_ptr<QTranslator> m_currentTranslator; // use one for each .qm

bool loadTranslationsForLanguage(const QString& lang) {
  QLocale::setDefault(lang);

  std::unique_ptr<QTranslator> translator(new QTranslator());
  if (!translator->load(":/translations/app.qm")) return false;

  qApp->removeTranslator(m_currentTranslator.get());
  qApp->installTranslator(translator.get());
  m_currentTranslator.swap(translator);

  return true;
}

关于c++ - 在 translations.qrc 文件中读取翻译器文件 .ts/.qm,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43326817/

相关文章:

c++ - 尝试调用 registerSource 时找不到 .rcc 文件

android - 大型 Qt 外部二进制资源文件

c++ - QML Component 'Video' 无法播放来自Qt资源文件的视频文件

c++ - JUCE - 成员函数不可行 : 'this' Argument Has Type const

c++ - Qt:正确地将撤消框架与 QGraphicsScene 集成

c++ - KDB C++ API : creating a list of strings

c++ - 如何只在 Debug模式下编译一段源代码?

c++:什么时候使用指针?

c++ - 类似项目中的 MessageBox 行为

c++ - 将 double 插入 char* 数组元素