为什么我需要用pyqtSlot装饰连接的插槽?

Why do I need to decorate connected slots with pyqtSlot?

我使用的是 pyqt5,我有几个方法使用类似于以下的代码连接:

self.progress.canceled.connect(self.cancel)

其中,例如,self.cancel 是:

def cancel(self):
    self.timer.stop()

此代码似乎在多种情况下都能正常工作,无需使用 pyqtSlot 装饰 cancel 或对其进行任何特殊操作。

我的问题是:

  1. 这样做我失去了什么?
  2. 为什么需要pyqtSlot

pyqtSlot is to allow several different overloads of a slot to be defined, each with a different signature. It may also be needed sometimes when making cross-thread connections (see this answer 的主要目的是针对其中一种情况)。但是,这些用例相对较少,在大多数 PyQt 应用程序中根本没有必要使用 pyqtSlot。信号可以连接到任何 python 可调用对象,无论它是否装饰为插槽。

PyQt 文档还声明:

Connecting a signal to a decorated Python method also has the advantage of reducing the amount of memory used and is slightly faster.

然而,在实践中,这种优势通常很小,而且往往会被其他因素淹没。它对原始信号传输速度影响很小,在它开始对 cpu 负载或内存使用情况。有关这些要点的深入分析,请参阅@Schollii 的这篇代码项目文章:

另一个好处是当你为Qt-designer设计自定义widgets时,pyqtSlot装饰的方法可以在Signal/Slot Editor内选择,否则你需要编写代码。