Bootstrap

【Qt QML】动态加载翻译

1 实现功能

动态加载不同语言

在这里插入图片描述

2 基础

【Qt QML】Qt Linguist使用方法,国际化,翻译

3 动态加载

3.1 languageset.h

#ifndef LANGUAGESET_H
#define LANGUAGESET_H

#include <QObject>
#include <QGuiApplication>
#include <QtWidgets/QApplication>
#include <QQmlApplicationEngine>
#include <QTranslator>

class LanguageSet : public QObject
{
    Q_OBJECT
public:
    explicit LanguageSet(QApplication& app, QQmlApplicationEngine& engine);

    Q_INVOKABLE void setLanguage(QString language);
    Q_INVOKABLE int getLanguageIdx(QString language);
    Q_INVOKABLE QString getLanguageName(int idx);

private:
    QApplication* m_app;
    QQmlApplicationEngine* m_engine;
    QList<QString> m_langList;
    QTranslator* m_translator;

signals:

};

#endif // LANGUAGESET_H

3.2 languageset.cpp

#include "languageset.h"

LanguageSet::LanguageSet(QApplication& app, QQmlApplicationEngine& engine)
{
    m_app = &app;
    m_engine = &engine;
    m_translator = new QTranslator();

    m_langList.append("zh_CN");
    m_langList.append("en_US");
}

/**
 * @brief 语言设置,支持qml
 * @param language: zh_CN, en_US
 */
void LanguageSet::setLanguage(QString language)
{
    if(language == "zh_CN")
    {
        m_translator->load("zh_CN.qm");
    }
    else if(language == "en_US")
    {
        m_translator->load("en_US.qm");
    }

    m_app->installTranslator(m_translator);
    m_engine->retranslate();
}

/**
 * @brief 获取语言编号
 * @param language
 * @return  zh_CN:0
 *          en_US:1
 */
int LanguageSet::getLanguageIdx(QString language)
{
    for(int i=0; i<m_langList.length(); i++){
        if(language == m_langList.at(i)){
            return i;
        }
    }

    return 0;
}

/**
 * @brief 获取语言名称
 * @param idx
 * @return
 */
QString LanguageSet::getLanguageName(int idx)
{
    if(idx >= m_langList.length())
        m_langList.at(0);

    return m_langList.at(idx);
}


3.3 main.cpp

#include <QGuiApplication>
#include <QtWidgets/QApplication>
#include <QQmlApplicationEngine>
#include <QDir>
#include <QQmlContext>
#include "Cpp/languageset.h"


int main(int argc, char *argv[])
{
    qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));

#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
    QApplication app(argc, argv);

    QQmlApplicationEngine engine;

    //Settings设置
    app.setOrganizationName("custom");
    app.setOrganizationDomain("com.custom");
    app.setApplicationName("test");
    QSettings _mGlobalSettings;

    //  ------  载入翻译 -------
    LanguageSet languageSet(app, engine);
    QString lang = _mGlobalSettings.value("_mLanguage", "zh_CN").toString();
    languageSet.setLanguage(lang);
	//暴露给qml
    engine.rootContext()->setContextProperty("_mLanguageSet", &languageSet);
    //  ------  载入翻译 -------


    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
        &app, [url](QObject *obj, const QUrl &objUrl) {
            if (!obj && url == objUrl)
                QCoreApplication::exit(-1);
        }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

3.4 qml中使用

MyComboBox{
	id: _mLang
	height: 50
	width: 500
	_mName: qsTr("语言")
	_mModel: ['简体中文', 'English']
	_mCurrentIndex: _mLanguageSet.getLanguageIdx(_mGlobalSettings.value("_mLanguage", "zh_CN"))
	
	on_MCurrentIndexChanged: {
	    //语言修改
	    if(_mCurrentText == "") return;
	    _mGlobalSettings._mLanguage = _mLanguageSet.getLanguageName(_mCurrentIndex)
	    _mLanguageSet.setLanguage(_mGlobalSettings._mLanguage)
	}
}

4. 注意

languageset.cpp中的setLanguage()函数要注意。

  • m_translator要在上创建
  • 如果在上创建,函数执行完毕就销毁了,导致翻译没有效果
void LanguageSet::setLanguage(QString language)
{
    if(language == "zh_CN")
    {
        m_translator->load("zh_CN.qm");
    }
    else if(language == "en_US")
    {
        m_translator->load("en_US.qm");
    }

    m_app->installTranslator(m_translator);
    m_engine->retranslate();
}

5. 参考

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;