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的值:
- 修改
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; };
- 实现
locale()方法并在selectLanguage中更新:
QLocale Translator::locale() const { return m_locale; } void Translator::selectLanguage(QString language) { // 保留原有加载翻译的代码 m_locale = QLocale(language); emit languageChanged(); }
- 在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
相关产品推荐
相关产品推荐

