Прочитать файл переводчика .ts / .qm в файле translations.qrc

Я пытаюсь импортировать файл переводчика в моем проекте 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. Как я могу решить эту проблему?

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

Подробнее о настройке локали в этот ответ.

Замена переводчиков

Если вы уже загрузили переводчик, то вы столкнетесь с новыми проблемами, так как 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;
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]