Pylance 在 self.tr() 方法上报错
我正在用 PySide6 6.6.2 和 Python 3.11.8 开发一个应用程序,一切运行得很好,mypy 也没有问题。不过,正如我在下面的图片中展示的那样,Pylance(在 VSCode 中)一直在抱怨说 self.tr()
不能被访问,尽管实际上它应该可以被任何 QtCore.QObject
(因此也包括 QtWidgets.QWidget
)访问。实际上,应用程序运行得没有错误,pyside6-lupdate
和 pyside6-lrelease
也都没有问题。
这里是示例代码:
from PySide6 import QtWidgets
class TestWidget(QtWidgets.QWidget):
def __init__(self):
super(TestWidget, self).__init__()
self.setLayout(QtWidgets.QVBoxLayout())
self.layout().addWidget(QtWidgets.QLabel(self.tr("Hello World!")))
据我所知,Qt 的类型定义文件是和库一起打包的。为什么只有这个特定的方法不能正常工作呢?为什么我需要手动为一个方法添加类型定义,而整个包的其他部分都能正确检查类型(例如,self.setLayout
和 self.layout()
都能正确检查)?这让我觉得可能是我使用 QTranslator 的方式有问题,而不是库本身的问题。
我尝试这样手动实现 self.tr()
:
from PySide6 import QtWidgets, QtCore
class TestWidget(QtWidgets.QWidget):
def __init__(self):
super(TestWidget, self).__init__()
self.setLayout(QtWidgets.QVBoxLayout())
self.layout().addWidget(QtWidgets.QLabel(self.tr("Hello World!")))
def tr(self, text: str) -> str:
return QtCore.QCoreApplication.translate("TestWidget", text)
这样做让 Pylance 满意,应用程序仍然可以正常工作。不过,我觉得很奇怪,为什么我需要手动实现这个方法,而 文档 本身也在使用它们(而且如果我直接下载那个示例,还是会出现同样的错误)。
有没有人能帮我理解发生了什么?
1 个回答
正如@musicamante在回复中提到的,QObject.tr()
是一个C++中的静态方法,专门用于QObject
类。文档中明确说明:
不幸的是,由于Qt实现
tr()
的方式,PyQt6无法完全复制它的行为。[...] PyQt6的行为并不理想,未来可能会有所改变。建议使用translate()
,而不是tr()
。这样可以确保在当前和未来的PyQt6版本中都能正常工作,并且更容易在Python和C++代码之间共享消息文件。
因此,我写的实现方式可能是个不错的选择,使用QtCore.QCoreApplication.translate()
,如果需要的话,可以为你的类手动实现self.tr()
。
以下是上面链接中的示例:
from PySide6 import QtCore
class A(QtCore.QObject):
def hello(self):
return QtCore.QCoreApplication.translate('A', "Hello")
a = A()
a.hello() # Correctly translated