You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt QML中qsTr需搭配emptyString才能翻译的原因及解决方法

关于QML中qsTr翻译依赖translator.emptyString的问题解答

问题描述

在Qt QML开发中配置了名为translator的翻译器后,出现以下现象:

  • 当使用如下代码时,能正常获取翻译后的内容(例如显示“Whatever message”):
Text {
     id: title
     text: qsTr("title") + translator.emptyString
}
  • 但去掉+ translator.emptyString后,无法触发翻译,仍显示原字符串“title”:
Text {
     id: title
     text: qsTr("title")
}

相关代码如下:

Translator类实现

#include "translator.h"
#include <QDebug>
#include <QGuiApplication>
#include <QDir>

Translator::Translator()
{
    translator = new QTranslator(this);
}

QString Translator::getEmptyString()
{
    return QString();
}

void Translator::selectLanguage(QString language)
{
    if (!translator->load(
            // 示例:"pt"语言对应文件为qedgeui_pt.qm,后缀自动添加
            QString("ui_%1").arg(language), ":/i18n"
            )
        )
    {
        qDebug() << "Failed to load translation for " << language;
    }
    else {
        qDebug() << "Translator language" << language << "loaded: " << QString("ui_%1").arg(language) << ":/i18n";
    }
    if (!qApp->installTranslator(translator))
    {
        qDebug() << "Failed to install translation for " << language;
    }

    emit languageChanged();
}

main函数代码

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

#include "translator.h"

int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
    QApplication app(argc, argv);

    QQmlApplicationEngine engine;

    Translator translator;

    auto context = engine.rootContext();
    context->setContextProperty("translator", &translator);

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

    translator.selectLanguage("en");
    qDebug() <<  QApplication::translate("Header", "title", 0); // 此处翻译正常


    return app.exec();
}

原因分析

添加translator.emptyString能触发翻译,本质是因为这个操作让QML的属性绑定感知到了translator对象的languageChanged信号,从而重新计算text属性的值——此时qsTr会使用新加载的翻译文件。

而直接写qsTr("title")时,QML引擎会在初始加载时计算一次值并缓存,后续加载翻译文件后,没有信号通知该属性需要重新计算,所以不会更新为翻译后的内容。

解决方案

方案1:绑定Locale属性触发自动刷新

通过给Translator类添加locale属性,让QML感知语言变化并自动重新计算qsTr的值:

  1. 修改translator.h,添加locale属性:
#include <QLocale>

class Translator : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QLocale locale READ locale NOTIFY languageChanged)

public:
    explicit Translator(QObject *parent = nullptr);
    QLocale locale() const;
    // 保留原有方法声明

private:
    QTranslator *translator;
    QLocale m_locale;
};
  1. 实现locale()方法并在selectLanguage中更新:
QLocale Translator::locale() const
{
    return m_locale;
}

void Translator::selectLanguage(QString language)
{
    // 保留原有加载翻译的代码

    m_locale = QLocale(language);
    emit languageChanged();
}
  1. 在QML中绑定locale:
Text {
    id: title
    locale: translator.locale
    text: qsTr("title")
}

当locale变化时,QML会自动重新计算qsTr的值,触发翻译更新。

方案2:提前加载翻译(适合无需动态切换语言的场景)

如果应用启动时就确定语言,可以在加载QML前调用selectLanguage,让QML初始加载时就使用正确的翻译:

// main.cpp中调整代码顺序
translator.selectLanguage("en");
engine.load(url);

方案3:手动触发QML重翻译(Qt 5.14+支持)

在selectLanguage方法中,调用QQmlEngine的retranslate()方法强制刷新所有翻译内容:

// 需要在Translator类中持有QQmlEngine的指针,或通过全局方式获取
engine->retranslate();

这种方式适合需要批量刷新翻译的场景,但不如绑定locale优雅。

内容的提问来源于stack exchange,提问作者Mendes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 07:57:06