考虑以下最小工作示例:
#!/usr/bin/env python3
from PySide6.QtCore import QTimer
from PySide6.QtWidgets import QLabel, QApplication
app = QApplication()
label = QLabel('Label')
x = 0
def timeout():
global x
x += 1
label.setText(str(x))
timer = QTimer()
timer.timeout.connect(timeout)
timer.start(200)
label.show()
app.exec()
它显示一个标签(一个非常的小窗口),包含一个递增的计数器。这一切都很好。但是,我使用 PyLance 扩展在 Visual Studio Code 中进行开发,IDE 不知道
timeout
信号QTimer
:
很公平,按 F12 打开
QtCore.pyi
和 QTimer
的定义,这实际上 not 包含一个 timeout
成员:
class QTimer(PySide6.QtCore.QObject):
def __init__(self, parent:Optional[PySide6.QtCore.QObject]=...) -> None: ...
def interval(self) -> int: ...
def isActive(self) -> bool: ...
def isSingleShot(self) -> bool: ...
def killTimer(self, arg__1:int) -> None: ...
def remainingTime(self) -> int: ...
def setInterval(self, msec:int) -> None: ...
def setSingleShot(self, singleShot:bool) -> None: ...
def setTimerType(self, atype:PySide6.QtCore.Qt.TimerType) -> None: ...
@overload
@staticmethod
def singleShot(arg__1:int, arg__2:Callable) -> None: ...
@overload
@staticmethod
def singleShot(msec:int, receiver:PySide6.QtCore.QObject, member:bytes) -> None: ...
@overload
@staticmethod
def singleShot(msec:int, timerType:PySide6.QtCore.Qt.TimerType, receiver:PySide6.QtCore.QObject, member:bytes) -> None: ...
@overload
def start(self) -> None: ...
@overload
def start(self, msec:int) -> None: ...
def stop(self) -> None: ...
def timerEvent(self, arg__1:PySide6.QtCore.QTimerEvent) -> None: ...
def timerId(self) -> int: ...
def timerType(self) -> PySide6.QtCore.Qt.TimerType: ...
这显然不限于
QTimer
,但也适用于例如对于QAbstractButton
,不包括clicked
、pressed
、released
和toggled
。简而言之,看起来好像所有信号都从对象中丢失了。
这里发生了什么?除了
pip install pyside6
之外,我还需要安装其他东西来获取输入中定义的所有信号吗?当然,这不是一个障碍,但如果 IDE 知道对象的所有成员会更方便。
以防万一,我使用 Ubuntu 20.04 的 python3:
$ python3
Python 3.8.10 (default, Nov 26 2021, 20:14:08)
[GCC 9.3.0] on linux
这个问题已经存在很长时间了,即使在PyQt中也是如此。我认为像clicked, pressed这样的“slot”将是实例的一个属性,当Qt程序运行时它会被动态链接库使用。你在 Python 代码中所做的只是分配稍后将使用的属性,因此它不会出现在使 pylance 不知道它的键入文件中。