Qt CMake项目转基于ID的翻译模型后仍带上下文的问题
问题描述
我有一个纯Widget的Qt CMake项目(无QML),当前仅包含一个带菜单和若干控件的MainWindow。最初采用默认的基于明文的翻译机制,现需切换为基于文本ID的翻译机制,且已在CMakeLists.txt的qt_add_translations(... LRELEASE_OPTIONS ...)中添加了-idbased选项。我了解基于文本ID的翻译机制不存在上下文,但在Ui_MainWindow::retranslateUi函数中,仍存在大量如下形式的代码(添加-idbased选项前便已存在):
menuHelp->setTitle(QCoreApplication::translate("MainWindow", "id-help", nullptr));
即菜单项Help的文本ID为"id-help",且处于"MainWindow"上下文之中,这令我困惑。请问是我的预期有误,还是操作存在问题?如何让Qt Creator生成无上下文的翻译条目?
问题原因
这是因为你仅配置了lrelease的-idbased选项,该选项只影响翻译文件(.qm)的生成逻辑,但Qt Creator的uic工具(负责生成UI代码)默认仍会为控件生成带上下文的翻译调用,两者的配置是独立的。
解决方法
1. 通过UI设计器设置无上下文的翻译ID
打开目标.ui文件,进入设计模式:
- 选中需要设置翻译ID的控件(如Help菜单)
- 在右侧属性面板找到
text属性,点击旁侧的翻译图标(小地球) - 在弹出的翻译对话框中,切换到“使用ID”模式,输入指定ID(如"id-help"),同时不指定上下文
- 保存UI文件,重新编译项目,uic会生成无上下文的翻译调用代码
2. 配置CMake强制uic生成无上下文代码
在CMakeLists.txt中添加以下配置,强制uic生成不带上下文的翻译调用:
# 强制uic生成无上下文的翻译函数调用 set(CMAKE_AUTOUIC_OPTIONS "-no-tr-context")
添加后重新运行CMake并编译,生成的retranslateUi函数中的代码会变为:
menuHelp->setTitle(QCoreApplication::translate("", "id-help", nullptr));
3. 手动修改生成的UI代码(临时方案)
若需临时验证,可以手动修改ui_MainWindow.h中retranslateUi函数的翻译调用,将上下文参数改为空字符串""。但注意:后续修改UI文件并重新生成代码时,手动修改的内容会被覆盖,仅适合临时测试。
预期纠正
你的核心预期是正确的:ID-based翻译机制下,上下文并非必需,翻译条目通过ID唯一标识,而非“上下文+原文”的组合。但需同时配置uic和lrelease两个工具,才能完全实现无上下文的ID-based翻译流程。
内容的提问来源于stack exchange,提问作者Dialecticus

