状态:
www.pythonguis.com学习如何在
PyQt
库中使用并发/线程。以下是本教程的简化/部分代码。mypy
收到有关此代码的错误消息。 (显示在第二个源代码块上)。问题:
pyqtSlot()
装饰器时正确提示函数?Superclass
(返回 None
),什么是 Subclass
(返回 str|None
)?我试图解决的问题:
stub
文件)说pyqtSlot()
是:
def pyqtSlot(*types, name: typing.Optional[str] = ..., result: typing.Optional[str] = ...) -> typing.Callable[..., typing.Optional[str]]: ...
,由于没有装饰器经验,我无法解释这一点。stub
文件:QtCore.pyi
表示 Class QRunnable
的 run
是:def run(self) -> None: ...
。from typing import Callable
from PyQt5.QtCore import QObject, QRunnable, pyqtSignal, pyqtSlot
import traceback
import sys
class WorkerSignal(QObject):
finished = pyqtSignal()
error = pyqtSignal(tuple)
result = pyqtSignal(object)
progress = pyqtSignal(int)
class Worker(QRunnable):
def __init__(self, fn: Callable[[], str]) -> None:
super(Worker, self).__init__()
self.fn:Callable[[], str] = fn
self.signals: WorkerSignal = WorkerSignal()
@pyqtSlot()
def run(self) -> None: # <====================== this line
try:
result: str = self.fn()
except Exception:
traceback.print_exc()
exctype, value = sys.exc_info()[:2]
self.signals.error.emit((exctype, value, traceback.format_exc()))
else:
self.signals.result.emit(result)
finally:
self.signals.finished.emit()
$ mypy /tmp/tmp.py
/tmp/tmp.py:22: error: Signature of "run" incompatible with supertype "QRunnable" [override]
/tmp/tmp.py:22: note: Superclass:
/tmp/tmp.py:22: note: def run(self) -> None
/tmp/tmp.py:22: note: Subclass:
/tmp/tmp.py:22: note: str | None
Found 1 error in 1 file (checked 1 source file)
编辑:
pyqtSlot()
接受返回 typing.Optional[str]
的函数(即 str | None
)。也许是subclass
?QRunnable
的方法run()
只返回None
,也许这就是superclass
?decorator's return
和 function's return
不同,如何使用装饰器?这是正确的问题吗?您不应该在 QRunnable 的 run 方法中使用 pyqtSlot。
pyqtSlot 装饰器仅在继承自 QObject 的类的方法中使用,而 QRunnable 则不使用。我已经回顾了几个采用这种不良做法的教程,因为它不会带来任何好处。