PySide6-lupdate中tr方法上下文判定差异原因及统一为类名的方法
PySide6-lupdate中tr方法上下文差异的原因与统一方案
问题场景
使用PySide6-lupdate生成.ts翻译文件时,不同方式调用tr()会生成不同的上下文:
测试代码
from PySide6.QtCore import QObject class Foo(QObject): def info(self): return self.tr('inside') Bar = Foo() Bar.tr('outside') self = Foo() self.tr('special one')
生成的.ts文件片段
<context> <name>Bar</name> <message> <location filename="../test.py" line="11"/> <source>outside</source> <translation type="unfinished"></translation> </message> </context> <context> <name>Foo</name> <message> <location filename="../test.py" line="8"/> <source>inside</source> <translation type="unfinished"></translation> </message> <message> <location filename="../test.py" line="12"/> <source>special one</source> <translation type="unfinished"></translation> </message> </context>
上下文差异总结
- 类定义内部调用
self.tr(),上下文为类名Foo - 普通变量名实例(
Bar)调用tr(),上下文为变量名Bar - 变量名为
self的实例调用tr(),上下文为类名Foo
差异原因
- 类内部的self调用:在类定义范围内,
self明确指向当前类的实例,lupdate通过静态分析能关联到类Foo,因此上下文使用类名。 - 普通变量实例调用:Python是动态类型语言,lupdate作为静态分析工具,无法在编译阶段确定
Bar的实际类型,只能退而求其次用变量名作为上下文标识。 - self变量的特殊处理:
self是Python类方法约定俗成的实例参数名,lupdate对这个名称做了硬编码的特殊识别——即使在类外部定义self = Foo(),也会被判定为类实例引用,从而使用类名作为上下文。
统一上下文为类名的方案
要确保所有tr()调用的上下文都是类名,可采用以下几种可靠方式:
1. 直接通过类名调用tr方法
调用类的tr静态方法,第一个参数传入实例对象,lupdate能明确识别上下文为类名:
Bar = Foo() Foo.tr(Bar, 'outside') # 上下文为Foo self = Foo() Foo.tr(self, 'special one') # 上下文为Foo
2. 使用QCoreApplication.translate指定上下文
直接指定翻译上下文为类名,绕过实例调用的上下文推断:
from PySide6.QtCore import QCoreApplication Bar = Foo() QCoreApplication.translate('Foo', 'outside') self = Foo() QCoreApplication.translate('Foo', 'special one')
3. 给变量添加类型注解(辅助识别)
如果必须用实例调用,给变量添加类型注解,帮助lupdate识别类型(部分场景有效,依赖工具的类型分析能力):
Bar: Foo = Foo() Bar.tr('outside') # 多数情况下会识别上下文为Foo
内容的提问来源于stack exchange,提问作者Djing
相关产品推荐
相关产品推荐

