3

我正在尝试在我的 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”始终为“假”。我该如何解决这个问题?

4

1 回答 1

4

首先,您的 .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 会为当前的 locale使用适当的文件。它对于在设计时指定的其他资源(如图像)特别有用,或者只是为了减少代码混乱。

注意:请参阅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;
}

有关在此答案中设置语言环境的更多信息。

更换翻译器

如果您已经加载了翻译器,那么您将面临新的挑战,因为 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;
}
于 2017-04-10T16:52:06.720 回答