Qt 5.15非UI/QML项目动态切换语言:已创建控件翻译更新方案
Qt5.15 已创建控件多语言更新方案
你遇到的问题本质是:tr()仅在控件初始化时执行一次并设置文本,安装/移除翻译器不会自动触发已创建控件的文本更新,必须手动重新触发翻译逻辑。以下是具体解决步骤:
核心解决思路
- 给每个自定义窗口/控件类添加手动重翻译方法,负责重新设置所有控件的文本(再次调用
tr())。 - 重写
changeEvent()方法,监听QEvent::LanguageChange事件(Qt在翻译器变更后会自动发送该事件),在事件触发时调用重翻译方法。 - 切换语言后,主动触发全局的语言变更事件,确保所有已创建窗口都能收到通知。
代码修改示例
1. 修改LanguageSettingPage类,添加重翻译和事件处理
首先在头文件声明方法:
class LanguageSettingPage : public SettingsPage { Q_OBJECT public: explicit LanguageSettingPage(SettingsDialog* d); private slots: void translate(); void untraslate(); void retranslateUi(); // 新增重翻译方法 protected: void changeEvent(QEvent* event) override; // 重写事件处理 private: QTranslator* m_language_translator; QPushButton* m_button_it; QPushButton* m_button_eng; };
然后实现cpp部分:
LanguageSettingPage::LanguageSettingPage(SettingsDialog* d): SettingsPage(d), m_language_translator(new QTranslator(this)) { auto* lh = new QHBoxLayout(this); m_button_it = new QPushButton; m_button_eng = new QPushButton; lh->addWidget(m_button_it); lh->addWidget(m_button_eng); connect(m_button_it, &QPushButton::clicked, this, &LanguageSettingPage::translate); connect(m_button_eng, &QPushButton::clicked, this, &LanguageSettingPage::untraslate); retranslateUi(); // 初始化时调用重翻译 this->translate(); } void LanguageSettingPage::retranslateUi() { // 重新设置所有控件的文本,此时tr()会使用当前激活的翻译器 m_button_it->setText(tr("Italia")); m_button_eng->setText(tr("English")); } void LanguageSettingPage::changeEvent(QEvent* event) { SettingsPage::changeEvent(event); if (event->type() == QEvent::LanguageChange) { retranslateUi(); // 收到语言变更事件时更新文本 } } void LanguageSettingPage::translate() { m_language_translator->load("Language_It_it"); qApp->installTranslator(m_language_translator); // 发送全局语言变更事件,通知所有窗口 qApp->postEvent(qApp, new QEvent(QEvent::LanguageChange)); } void LanguageSettingPage::untraslate() { qApp->removeTranslator(m_language_translator); // 同样发送事件触发更新 qApp->postEvent(qApp, new QEvent(QEvent::LanguageChange)); }
2. 对其他已创建窗口/控件的处理
所有需要支持动态翻译的自定义类,都要按照上述模式添加retranslateUi()和重写changeEvent(),确保它们能响应LanguageChange事件。
注意事项
- 确保翻译文件(
.qm)路径正确,load()方法如果只传文件名,需要保证文件在程序运行路径下,或者使用绝对路径。 - 对于Qt内置控件(比如QMessageBox等动态创建的弹窗),只要在创建时调用
tr(),切换语言后新创建的弹窗会自动使用新翻译,无需额外处理。 - 复杂自定义控件(如包含子控件的容器类),要确保
retranslateUi()遍历所有子控件并更新文本。
内容的提问来源于stack exchange,提问作者sQula
相关产品推荐
相关产品推荐

