在 translations.qrc 文件中读取翻译器文件 .ts/.qm
Posted
技术标签:
【中文标题】在 translations.qrc 文件中读取翻译器文件 .ts/.qm【英文标题】:Read translator file .ts/.qm on translations.qrc file 【发布时间】:2017-04-10 15:10:01 【问题描述】:我正在尝试在我的 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”始终为“假”。我该如何解决这个问题?
【问题讨论】:
你确定资源文件被编译成二进制文件吗? 试试我的解决方案:P 【参考方案1】:首先,您的 .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;
【讨论】:
我遵循了您的建议,但 isFileTranslatorLoaded 始终返回 false。我修改了我的源代码: bool isFileTranslatorLoaded = translate->load(":/translations/navisit.qm");资源文件是:QLocale::setDefault("it");
之类的东西?
不,我没有设置 QLocale。在调用加载函数之前,如何在 main.cpp 文件中配置 QLocale?感谢您的建议
没什么,我已经听从了你的建议,但是 .qm 文件没有加载,可能是 qt 5.6 套件有问题。如doc.qt.io/qt-5/qtlinguist-hellotr-example.html 所述,我还在 Windows 上创建了一个项目,但加载 .qm 文件失败。我不知道如何使用 qtranslator。这似乎很容易,但行不通。
这并不难,在某些时候可能会很棘手,但并不难。我已经使用它们好几年了,非常棒。可能还有很多其他的失败点,所以我建议你编辑你的问题并发布一个minimal reproducible example,这是一个简单的项目,它有一个派生自QObject
的类,并在构造函数中使用类似qDebug() << tr("Hello world!");
的东西。在您的main()
函数中,只需创建QApplication
,加载翻译,创建类并退出(字符串将在构造函数中打印出来)。然后,运行lupdate
和lrelease
工具来创建翻译。以上是关于在 translations.qrc 文件中读取翻译器文件 .ts/.qm的主要内容,如果未能解决你的问题,请参考以下文章
深入理解计算机系统 1.4 处理器读取和解释存储在内存中的指令