在translations.qrc文件中读取翻译文件.ts / .qm

时间:2017-04-10 15:10:01

标签: c++ qt qt-resource qtranslator

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

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

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

false

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

项目文件:

testTrl.pro文件:

/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
...

translations.qrc文件:

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

main.cpp文件:

<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>

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

1 个答案:

答案 0 :(得分:0)

首先,您的.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;
}