Я пытаюсь импортировать файл переводчика в моем проекте Qt (Qt 5.6 в системе Linux), но я не могу загрузить файл перевода, потому что 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
...
Я получил файлы «.ts» и «.qm» с помощью команд «lrelease» и «lupdate».
Файлы проекта:
Файл 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;
}
Подробнее о настройке локали в этот ответ.
Замена переводчиков
Если вы уже загрузили переводчик, то вы столкнетесь с новыми проблемами, так как 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;
}
Других решений пока нет …