QString常量可重译吗?类常量实现多语言适配正确性咨询
1. 能否对const QString类型的字符串调用tr()进行重译?
答案是不能,或者说这么做完全达不到你想要的重译效果。
原因很简单:tr()的核心作用是标记原始的、未翻译的源字符串(通常是硬编码的const char*字面量),让Qt的lupdate工具能够识别并提取这些字符串到.ts翻译文件中。如果你拿一个已经是QString(哪怕是const修饰的)的对象传给tr(),首先lupdate根本不会把它当作待翻译的源字符串——它只会识别直接传入的字符串字面量;其次,就算你强行这么做,这个const QString的内容是固定的,切换语言时也无法触发重新翻译,因为tr()在这里只是对已有的字符串做无意义的包装,不会去查找新语言的翻译条目。
2. 类常量const QString的实现方式能否支持动态重译?
你的代码写法无法支持动态重译,切换语言时不会自动更新这个常量的内容。
问题出在哪?
const QString是类的常量成员,它的初始化发生在对象构造阶段——一旦对象创建完成,这个常量的值就被固定死了,再也无法修改。而Qt的动态重译机制,需要在语言切换时(比如用户切换系统语言或应用内语言设置),重新调用tr()来获取对应语言的翻译结果,然后更新UI或相关字符串。你的NEW_LABEL_TEXT在构造时就用tr()初始化了,之后再也没法更新,所以切换语言后它还是构造时的那个翻译版本,不会变化。
正确的实现方式
要兼顾“避免#define”和“支持动态重译”,推荐以下两种方案:
方案1:使用静态常量字符数组
在头文件中定义静态的常量const char*,在需要使用的地方再用tr()包裹:
// myclass.h class MyClass : public QDialog { Q_OBJECT // 别忘了这个宏,tr()依赖它 private: Ui::MyClassWidget* ui; static constexpr const char* NEW_LABEL_TEXT = "---New label---"; }; // myclass.cpp MyClass::MyClass() : ui(new Ui::MyClassWidget) { // 使用时调用tr() ui->someLabel->setText(tr(NEW_LABEL_TEXT)); }
方案2:重写changeEvent实现动态重译
不管用哪种方式定义常量,要实现动态重译,都需要在类中重写changeEvent函数,处理语言切换事件:
void MyClass::changeEvent(QEvent* event) { QDialog::changeEvent(event); if (event->type() == QEvent::LanguageChange) { // 如果用了Qt Designer生成的UI,直接调用retranslateUi ui->retranslateUi(this); // 如果是手动设置的文本,重新调用tr()更新 ui->someLabel->setText(tr(NEW_LABEL_TEXT)); } }
这样一来,当语言切换时,所有调用tr()的地方都会重新获取当前语言的翻译结果,完美实现动态重译。
内容的提问来源于stack exchange,提问作者Armin the Crossman

